Introduction
à l’analyse d’enquêtes
avec R et RStudio

Dernière mise à jour : 12 novembre 2020

DOI: 10.5281/zenodo.2081968

Contributeurs

Par ordre alphabétique :

Julien Barnier, Julien Biaudet, François Briatte, Milan Bouchet-Valat, Ewen Gallic, Frédérique Giraud, Joël Gombin, Mayeul Kauffmann, Christophe Lalanne, Joseph Larmarange, Nicolas Robette.

Création et Maintenance :

Joseph Larmarange — http://joseph.larmarange.net

Présentation

L’objectif premier d’analyse-R est de présenter comment réaliser des analyses statistiques et diverses opérations courantes (comme la manipulation de données ou la production de graphiques) avec R. Il ne s’agit pas d’un cours de statistiques : les différents chapitres présupposent donc que vous avez déjà une connaissance des différentes techniques présentées. Si vous souhaitez des précisions théoriques / méthodologiques à propos d’un certain type d’analyses, nous vous conseillons d’utiliser votre moteur de recherche préféré. En effet, on trouve sur internet de très nombreux supports de cours (sans compter les nombreux ouvrages spécialisés disponibles en libraririe).

Table des matières

Si vous débutez avec R et RStudio, nous vous conseillons de parcourir en premier lieu les chapitres suivants :

  1. Manipuler > Prise en main
  2. Analyser > Statistiques introductives
  3. Manipuler > Manipulations de données
  4. Analyser > Statistiques intermédiares

puis de compléter votre lecture en fonction de vos besoins.

Licence

Le contenu de ce site est diffusé sous licence Creative Commons Attribution - Pas d’utilisation commerciale - Partage dans les mêmes conditions (https://creativecommons.org/licenses/by-nc-sa/3.0/fr/).

CC by-nc-sa

Cela signifie donc que vous êtes libre de recopier / modifier / redistribuer les contenus d’analyse-R, à condition que vous citiez la source et que vos modifications soient elle-mêmes distribuées sous la même licence (autorisant ainsi d’autres à pouvoir réutiliser à leur tour vos ajouts).

Contribuer

analyse-R est développé avec RStudio et le code source est librement disponible sur GitHub :
https://github.com/larmarange/analyse-R.

Ce projet se veut collaboratif. N’hésitez donc pas à proposer des corrections ou ajouts, voire même à rédiger des chapitres additionnels.

Présentation et Philosophie

Présentation de R

R est un langage orienté vers le traitement de données et l’analyse statistique dérivé du langage S. Il est développé depuis une vingtaine d’années par un groupe de volontaires de différents pays. C’est un logiciel libre1, publié sous licence GNU GPL.

L’utilisation de R présente plusieurs avantages :

  • c’est un logiciel multiplateforme, qui fonctionne aussi bien sur des sytèmes Linux, Mac OS X ou Windows ;
  • c’est un logiciel libre, développé par ses utilisateurs et modifiable par tout un chacun ;
  • c’est un logiciel gratuit ;
  • c’est un logiciel très puissant, dont les fonctionnalités de base peuvent être étendues à l’aide de plusieurs milliers d’extensions ;
  • c’est un logiciel dont le développement est très actif et dont la communauté d’utilisateurs ne cesse de s’élargir ;
  • les possibilités de manipulation de données sous R sont en général largement supérieures à celles des autres logiciels usuels d’analyse statistique ;
  • c’est un logiciel avec d’excellentes capacités graphiques et de nombreuses possibilités d’export ;
  • avec Rmarkdown2, il est devenu très aisé de produire des rapports automatisés dans divers format (Word, PDF, HTML, …) ;
  • R est de plus utilisé dans tous les secteurs scientifiques, y compris dans le domaine des analyses d’enquêtes et, plus généralement, des sciences sociales.

Comme rien n’est parfait, on peut également trouver quelques inconvénients :

  • le logiciel, la documentation de référence et les principales ressources sont en anglais. Il est toutefois parfaitement possible d’utiliser R sans spécialement maîtriser cette langue ;
  • il n’existe pas encore d’interface graphique pour R équivalente à celle d’autres logiciels comme SPSS ou Modalisa. R fonctionne à l’aide de scripts (des petits programmes) édités et exécutés au fur et à mesure de l’analyse et se rapprocherait davantage de SAS dans son utilisation (mais avec une syntaxe et une philosophie très différentes). Ce point, qui peut apparaître comme un gros handicap, s’avère après un temps d’apprentissage être un mode d’utilisation d’une grande souplesse ;
  • comme R s’apparente davantage à un langage de programmation qu’à un logiciel proprement dit, la courbe d’apprentissage peut être un peu « raide », notamment pour ceux n’ayant jamais programmé auparavant.

Il est à noter que le développement autour de R a été particulièrement actif ces dernières années. On trouvera dès lors aujourd’hui de nombreuses extensions permettant de se « faciliter la vie » au quotidien, ce qui n’était pas vraiment encore le cas il y a 5 ans.

Philosophie de R

Quelques points particuliers dans le fonctionnement de R peuvent parfois dérouter les utilisateurs habitués à d’autres logiciels :

  • Sous R, en général, on ne voit pas directement les données sur lesquelles on travaille ; on ne dispose pas en permanence d’une vue des données sous forme de tableau3, comme sous Modalisa ou SPSS. Ceci peut être déroutant au début, mais on se rend vite compte qu’on n’a pas besoin de voir en permanence les données pour les analyser.
  • Alors qu’avec la plupart des logiciels on réfléchira avec un fichier de données ouvert à la fois, sous R chaque fichier de données correspondra à un objet différent chargé en mémoire, permettant de manipuler très facilement plusieurs objets à la fois (par exemple dans le cadre de fusion de tables4).
  • Avec les autres logiciels, en général la production d’une analyse génère un grand nombre de résultats de toutes sortes dans lesquels l’utilisateur est censé retrouver et isoler ceux qui l’intéressent. Avec R, c’est l’inverse : par défaut l’affichage est réduit au minimum et c’est l’utilisateur qui demande à voir des résultats supplémentaires ou plus détaillés.
  • Sous R, les résultats des analyses sont eux aussi stockés dans des objets et sont dès lors manipulables.

Inhabituel au début, ce fonctionnement permet en fait assez rapidement de gagner du temps dans la conduite des analyses.

Présentation de RStudio

L’interface de base de R est assez rudimentaire (voir figure ci-après).

Interface de R sous Windows
Interface de R sous Windows

RStudio est un environnement de développement intégré libre, gratuit, et qui fonctionne sous Windows, Mac OS X et Linux. Il complète R et fournit un éditeur de script avec coloration syntaxique, des fonctionnalités pratiques d’édition et d’exécution du code (comme l’autocomplétion), un affichage simultané du code, de la console R, des fichiers, graphiques et pages d’aide, une gestion des extensions, une intégration avec des systèmes de contrôle de versions comme git, etc. Il intègre de base divers outils comme par exemple la production de rapports au format Rmarkdown. Il est en développement actif et de nouvelles fonctionnalités sont ajoutées régulièrement. Son principal défaut est d’avoir une interface uniquement anglophone.

Interface de RStudio sous Windows
Interface de RStudio sous Windows

Pour une présentation plus générale de RStudio on pourra se référer au site du projet : http://www.rstudio.com/.

RStudio peut tout à fait être utilisé pour découvrir et démarrer avec R. Les différents chapitres d’analyse-R partent du principe que vous utilisez R avec RStudio. Cependant, à part les éléments portant sur l’interface de RStudio, l’ensemble du code et des fonctions R peuvent être utilisés directement dans R, même en l’absence de RStudio.

La documentation de RStudio (en anglais) est disponible en ligne à https://support.rstudio.com. Pour être tenu informé des dernières évolutions de RStudio, mais également de plusieurs extensions développées dans le cadre de ce projet, vous pouvez suivre le blog dédié http://blog.rstudio.org/.


  1. Pour plus d’informations sur ce qu’est un logiciel libre, voir : http://www.gnu.org/philosophy/free-sw.fr.html.

  2. Voir http://rmarkdown.rstudio.com/.

  3. On verra qu’il est possible avec RStudio de disposer d’une telle vue.

  4. Voir par exemple la section dédiée à ce sujet dans le chapitre sur la manipulation de données.

Installation de R et RStudio

Il est préférable de commencer par installer R avant d’installer RStudio.

Installation de R

Pour une installation sous Windows, on se rendra sur cette page : http://cran.r-project.org/bin/windows/base/ et l’on suivra le premier lien pour télécharger le programme d’installation. Une fois le programme d’installation lancé, il suffira d’installer R avec les options par défaut1.

Pour Mac OS X, les fichiers d’installation sont disponibles à http://cran.r-project.org/bin/macosx/.

Si vous travaillez sous Linux, vous devriez pouvoir trouver R via votre gestionnaire de paquets, cela pouvant dépendre d’une distribution de Linux à une autre.

Installation de RStudio

Une fois R correctement installé, rendez-vous sur http://www.rstudio.com/products/rstudio/download/ pour télécharger la dernière version stable de RStudio. Plus précisément, il s’agit de l’édition Open Source de RStudio Desktop (en effet, il existe aussi une version serveur).

Choisissez l’installateur correspondant à votre système d’exploitation et suivez les instructions du programme d’installation.

Si vous voulez tester les dernières fonctionnalités de RStudio, vous pouvez télécharger la version de développement (plus riche en fonctionnalités que la version stable, mais pouvant contenir des bugs) sur http://www.rstudio.com/products/rstudio/download/preview/.

Mise à jour de R sous Windows

Pour mettre à jour R sous Windows, il suffit de télécharger et d’installer la dernière version du programme d’installation.

Petite particularité, la nouvelle version sera installée à côté de l’ancienne version. Si vous souhaitez faire de la place sur votre disque dur, vous pouvez désinstaller l’ancienne version en utilisant l’utilitaire Désinstaller un programme de Windows.

Lorsque plusieurs versions de R sont disponibles, RStudio choisit par défaut la plus récente. Il est vous est possible de spécifier à RStudio quelle version de R utiliser via le menu Tools > Global Options > General.

Petit défaut, les extensions (packages) sont installées par défaut sous Windows dans le répertoire Documents de l'utilisateur > R > win-library > x.y avec x.y correspondant au numéro de la version de R. Ainsi, si l’on travaillait avec la version 3.0 et que l’on passe à la version 3.2, les extensions que l’on avait sous l’ancienne version ne sont plus disponibles pour la nouvelle version. Une astuce consiste à recopier le contenu du répertoire 3.0 dans le répertoire 3.2. Puis, on lancera RStudio (s’il était déjà ouvert, on le fermera puis relancera) et on mettra à jour l’ensemble des packages, soit avec la fonction, update.packages soit en cliquant sur Update dans l’onglet Packages du quadrant inférieur droit.

Voir aussi

Un tutoriel détaillé en français sur le blog Quanti : https://quanti.hypotheses.org/1813.


  1. Dans le cas particulier où votre ordinateur est situé derrière un proxy, il est préférable de choisir Options de démarrage personnalisées lorsque cela vous sera demandé par le programme d’installation, puis Internet2 lorsqu’on vous demandera le mode de connexion à Internet. Ainsi, R utilisera par défaut la configuration internet du navigateur Internet Explorer et prendra ainsi en compte les paramètres du proxy.

Premier contact

Ce chapitre est inspiré de la section Prise en main du support de cours Introduction à R réalisé par Julien Barnier.

Une fois RStudio lancé, vous devriez obtenir une fenêtre similaire à la figure ci-après.

Interface de RStudio au démarrage
Interface de RStudio au démarrage

L’interface de RStudio est divisée en quatre quadrants :

Inutile de tout retenir pour le moment. Nous aborderons chaque outil en temps utile. Pour l’heure, concentrons-nous sur la console, c’est-à-dire le quadrant inférieur gauche.

L’invite de commandes

Au démarrage, la console contient un petit texte de bienvenue ressemblant à peu près à ce qui suit :

R version 3.2.0 (2015-04-16) -- "Full of Ingredients"
Copyright (C) 2015 The R Foundation for Statistical Computing
Platform: x86_64-w64-mingw32/x64 (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

>

suivi d’une ligne commençant par le caractère > et sur laquelle devrait se trouver votre curseur. Cette ligne est appelée l’invite de commande (ou prompt en anglais). Elle signifie que R est disponible et en attente de votre prochaine commande.

Nous allons tout de suite lui fournir une première commande. Tapez 2 + 3 dans la console et validez avec la touche Entrée.

2 + 3
[1] 5

En premier lieu, vous pouvez noter la convention typographique utilisée dans ce documents. Les commandes saisies dans la console sont indiquées sur un fond gris et précédé de R>. Le résultat renvoyé par R est quant à lui affiché juste en-dessous sur fond blanc.

Bien, nous savons désormais que R sait faire les additions à un chiffre1. Nous pouvons désormais continuer avec d’autres opérations arithmétiques de base :

8 - 12
[1] -4
14 * 25
[1] 350
-3 / 10
[1] -0.3
-0.3
[1] -0.3

On remarquera que R est anglo-saxon. Les nombres sont donc saisies « à l’anglaise », c’est-à-dire en utilisant le point (.) comme séparateur pour les décimales.

Une petite astuce très utile lorsque vous tapez des commandes directement dans la console : en utilisant les flèches Haut et Bas du clavier, vous pouvez naviguer dans l’historique des commandes tapées précédemment. Vous pouvez alors facilement réexécuter ou modifier une commande particulière.

Sous RStudio, l’onglet History du quadrant haut-droite vous permet de consulter l’historique des commandes que vous avez transmises à R.

Onglet History sous RStudio

Un double-clic sur une commande la recopiera automatiquement dans la console. Vous pouvez également sélectionner une ou plusieurs commandes puis cliquer sur To Console.

Voir également (en anglais) : https://support.rstudio.com/hc/en-us/articles/200526217-Command-History.

Lorsqu’on fournit à R une commande incomplète, celui-ci nous propose de la compléter en nous présentant une invite de commande spéciale utilisant les signe +. Imaginons par exemple que nous avons malencontreusement tapé sur Entrée alors que nous souhaitions calculer 4 * 3 :

4 *

On peut alors compléter la commande en saisissant simplement 3 :

4 *
+ 3
[1] 12

Pour des commandes plus complexes, il arrive parfois qu’on se retrouve coincé avec une invite + sans plus savoir comment compléter la saisie correctement. On peut alors annuler la commande en utilisant la touche Echap ou Esc sous Windows.

Sous Linux on utilise le traditionnel Control + C.

À noter que les espaces autour des opérateurs n’ont pas d’importance lorsque l’on saisit les commandes dans R. Les trois commandes suivantes sont donc équivalentes, mais on privilégie en général la deuxième pour des raisons de lisibilité du code.

10+2
10 + 2
10    +    2

Des objets

Objets simples

Faire des opérations arithmétiques, c’est bien, mais sans doute pas totalement suffisant. Notamment, on aimerait pouvoir réutiliser le résultat d’une opération sans avoir à le resaisir ou à le copier/coller.

Comme tout langage de programmation, R permet de faire cela en utilisant des objets. Prenons tout de suite un exemple :

x <- 2

Que signifie cette commande ? L’opérateur <- est appelé opérateur d’assignation. Il prend une valeur quelconque à droite et la place dans l’objet indiqué à gauche. La commande pourrait donc se lire mettre la valeur 2 dans l’objet nommé x.

Il existe trois opérateurs d’assignation sous R. Ainsi les trois écritures suivantes sont équivalentes :

x <- 2
x = 2
2 -> x

Cependant, pour une meilleure lecture du code, il est conseillé de n’utiliser que <-. Ainsi, l’objet créé est systématiquement affiché à gauche. De plus, le symbole = sert également pour écrire des conditions ou à l’intérieur de fonctions. Il est donc préférable de ne pas l’utiliser pour assigner une valeur (afin d’éviter les confusions).

On va ensuite pouvoir réutiliser cet objet dans d’autres calculs ou simplement afficher son contenu :

x + 3
[1] 5
x
[1] 2

Par défaut, si on donne à R seulement le nom d’un objet, il va se débrouiller pour nous présenter son contenu d’une manière plus ou moins lisible.

On peut utiliser autant d’objets qu’on veut. Ceux-ci peuvent contenir des nombres, des chaînes de caractères (indiquées par des guillemets droits doubles " ou simples ') et bien d’autres choses encore :

x <- 27
y <- 10
foo <- x + y
foo
[1] 37
x <- "Hello"
foo <- x
foo
[1] "Hello"

Les noms d’objets peuvent contenir des lettres, des chiffres, les symboles . et _. Ils doivent impérativement commencer par une lettre (jamais par un chiffre). R fait la différence entre les majuscules et les minuscules, ce qui signifie que x et X sont deux objets différents. On évitera également d’utiliser des caractères accentués dans les noms d’objets. Comme les espaces ne sont pas autorisés on pourra les remplacer par un point ou un tiret bas.

Enfin, signalons que certains noms courts sont réservés par R pour son usage interne et doivent être évités. On citera notamment c, q, t, C, D, F, I, T, max, min

Dans RStudio, l’onglet Environment dans le quadrant supérieur droit indique la liste des objets que vous avez précédemment créés, leur type et la taille qu’ils occupent en mémoire.

Onglet Environment de RStudio
Onglet Environment de RStudio

Vecteurs

Imaginons maintenant que nous avons interrogé dix personnes au hasard dans la rue et que nous avons relevé pour chacune d’elle sa taille en centimètres. Nous avons donc une série de dix nombres que nous souhaiterions pouvoir réunir de manière à pouvoir travailler sur l’ensemble de nos mesures.

Un ensemble de données de même nature constituent pour R un vecteur (en anglais vector) et se construit à l’aide d’une fonction nommée c2. On l’utilise en lui donnant la liste de nos données, entre parenthèses, séparées par des virgules :

tailles <- c(167, 192, 173, 174, 172, 167, 171, 185, 163, 170)

Ce faisant, nous avons créé un objet nommé tailles et comprenant l’ensemble de nos données, que nous pouvons afficher en saisissant simplement son nom :

tailles
 [1] 167 192 173 174 172 167 171 185 163 170

Que se passe-t-il s’il on créé un vecteur plus grand ?

c(144, 168, 179, 175, 182, 188, 167, 152, 163, 145, 176, 155, 156, 164, 167, 155, 157, 185, 155, 169, 124, 178, 182, 195, 151, 185, 159, 156, 184, 172)
 [1] 144 168 179 175 182 188 167 152 163 145 176 155 156 164
[15] 167 155 157 185 155 169 124 178 182 195 151 185 159 156
[29] 184 172

On a bien notre suite de trente tailles, mais on peut remarquer la présence de nombres entre crochets au début de chaque ligne ([1], [15] et [29]). En fait ces nombres entre crochets indiquent la position du premier élément de la ligne dans notre vecteur. Ainsi, le 167 en début de deuxième ligne est le 15e élément du vecteur, tandis que le 184 de la troisième ligne est à la 29e position.

On en déduira d’ailleurs que lorsque l’on fait :

2
[1] 2

R considère en fait le nombre 2 comme un vecteur à un seul élément.

On peut appliquer des opérations arithmétiques simples directement sur des vecteurs :

tailles <- c(167, 192, 173, 174, 172, 167, 171, 185, 163, 170)
tailles + 20
 [1] 187 212 193 194 192 187 191 205 183 190
tailles / 100
 [1] 1.67 1.92 1.73 1.74 1.72 1.67 1.71 1.85 1.63 1.70
tailles^2
 [1] 27889 36864 29929 30276 29584 27889 29241 34225 26569
[10] 28900

On peut aussi combiner des vecteurs entre eux. L’exemple suivant calcule l’indice de masse corporelle à partir de la taille et du poids :

tailles <- c(167, 192, 173, 174, 172, 167, 171, 185, 163, 170)
poids <- c(86, 74, 83, 50, 78, 66, 66, 51, 50, 55)
tailles.m <- tailles / 100
imc <- poids / (tailles.m^2)
imc
 [1] 30.84 20.07 27.73 16.51 26.37 23.67 22.57 14.90 18.82
[10] 19.03

Quand on fait des opérations sur les vecteurs, il faut veiller à soit utiliser un vecteur et un chiffre (dans des opérations du type v * 2 ou v + 10), soit à utiliser des vecteurs de même longueur (dans des opérations du type u + v).

Si on utilise des vecteurs de longueur différentes, on peut avoir quelques surprises. Quand R effectue une opération avec deux vecteurs de longueurs différentes, il recopie le vecteur le plus court de manière à lui donner la même taille que le plus long, ce qui s’appelle la règle de recyclage (recycling rule). Ainsi, c(1,2) + c(4,5,6,7,8) vaudra l’équivalent de c(1,2,1,2,1) + c(4,5,6,7,8).

On a vu jusque-là des vecteurs composés de nombres, mais on peut tout à fait créer des vecteurs composés de chaînes de caractères, représentant par exemple les réponses à une question ouverte ou fermée :

reponse <- c("Bac+2", "Bac", "CAP", "Bac", "Bac", "CAP", "BEP")
reponse
[1] "Bac+2" "Bac"   "CAP"   "Bac"   "Bac"   "CAP"   "BEP"  

Enfin, notons que l’on peut accéder à un élément particulier du vecteur en faisant suivre le nom du vecteur de crochets contenant le numéro de l’élément désiré. Par exemple :

reponse <- c("Bac+2", "Bac", "CAP", "Bac", "Bac", "CAP", "BEP")
reponse[2]
[1] "Bac"

Cette opération s’appelle l’indexation d’un vecteur. Il s’agit ici de sa forme la plus simple, mais il en existe d’autres beaucoup plus complexes. L’indexation des vecteurs et des tableaux dans R est l’un des éléments particulièrement souples et puissants du langage (mais aussi l’un des plus délicats à comprendre et à maîtriser). Nous en reparlerons dans le chapitre Vecteurs, indexation et assignation.

Sous RStudio, vous avez du remarquer que ce dernier effectue une coloration syntaxique. Lorsque vous tapez une commande, les valeurs numériques sont affichées dans une certaine couleur, les valeurs textuelles dans une autre et les noms des fonctions dans une troisième. De plus, si vous tapez une parenthèse ouvrante, RStudio va créer automatiquement après le curseur la parenthèse fermante correspondante (de même avec les guillements ou les crochets). Si vous placez le curseur juste après une parenthèse fermante, la parenthèse ouvrante correspondante sera surlignée, ce qui sera bien pratique lors de la rédaction de commandes complexes.

Des fonctions

Nous savons désormais faire des opérations simples sur des nombres et des vecteurs, stocker ces données et résultats dans des objets pour les réutiliser par la suite.

Pour aller un peu plus loin nous allons aborder, après les objets, l’autre concept de base de R, à savoir les fonctions. Une fonction se caractérise de la manière suivante :

  • elle a un nom ;
  • elle accepte des arguments (qui peuvent avoir un nom ou pas) ;
  • elle retourne un résultat et peut effectuer une action comme dessiner un graphique ou lire un fichier.

En fait rien de bien nouveau puisque nous avons déjà utilisé plusieurs fonctions jusqu’ici, dont la plus visible est la fonction c. Dans la ligne suivante :

reponse <- c("Bac+2", "Bac", "CAP", "Bac", "Bac", "CAP", "BEP")

on fait appel à la fonction nommée c, on lui passe en arguments (entre parenthèses et séparées par des virgules) une série de chaînes de caractères et elle retourne comme résultat un vecteur de chaînes de caractères, que nous stockons dans l’objet reponse.

Prenons tout de suite d’autres exemples de fonctions courantes :

tailles <- c(167, 192, 173, 174, 172, 167, 171, 185, 163, 170)
length(tailles)
[1] 10
mean(tailles)
[1] 173.4
var(tailles)
[1] 76.71

Ici, la fonction length nous renvoie le nombre d’éléments du vecteur, la fonction mean nous donne la moyenne des éléments du vecteur et fonction var sa variance.

Arguments

Les arguments de la fonction lui sont indiqués entre parenthèses, juste après son nom. En général les premiers arguments passés à la fonction sont des données servant au calcul et les suivants des paramètres influant sur ce calcul. Ceux-ci sont en général transmis sous la forme d’argument nommés.

Reprenons l’exemple des tailles précédent :

tailles <- c(167, 192, 173, 174, 172, 167, 171, 185, 163, 170)

Imaginons que le deuxième enquêté n’ait pas voulu nous répondre. Nous avons alors dans notre vecteur une valeur manquante. Celle-ci est symbolisée dans R par le code NA :

tailles <- c(167, NA, 173, 174, 172, 167, 171, 185, 163, 170)

Recalculons notre taille moyenne :

mean(tailles)
[1] NA

Et oui, par défaut, R renvoie NA pour un grand nombre de calculs (dont la moyenne) lorsque les données comportent une valeur manquante. On peut cependant modifier ce comportement en fournissant un paramètre supplémentaire à la fonction mean, nommé na.rm :

mean(tailles, na.rm = TRUE)
[1] 171.3

Positionner le paramètre na.rm à TRUE (vrai) indique à la fonction mean de ne pas tenir compte des valeurs manquantes dans le calcul.

Lorsqu’on passe un argument à une fonction de cette manière, c’est-à-dire sous la forme nom=valeur, on parle d’argument nommé.

NA signifie not available. Cette valeur particulière peut être utilisée pour indiquer une valeur manquante pour tout type de liste (nombres, textes, valeurs logique, etc.).

Quelques fonctions utiles

Récapitulons la liste des fonctions que nous avons déjà rencontrées :

Fonction Description
c construit un vecteur à partir d’une série de valeurs
length nombre d’éléments d’un vecteur
mean moyenne d’un vecteur de type numérique
var variance d’un vecteur de type numérique
+, -, *, / opérateurs mathématiques de base
ˆ passage à la puissance

On peut rajouter les fonctions de base suivantes :

Fonction Description
min valeur minimale d’un vecteur numérique
max valeur maximale d’un vecteur numérique
sd écart-type d’un vecteur numérique
: génère une séquence de nombres. 1:4 équivaut à c(1,2,3,4)

Aide sur une fonction

Il est très fréquent de ne plus se rappeler quels sont les paramètres d’une fonction ou le type de résultat qu’elle retourne. Dans ce cas on peut très facilement accéder à l’aide décrivant une fonction particulière avec ? ou help. Ainsi, pour obtenir de l’aide sur la fonction mean, on saisira l’une des deux entrées équivalentes suivantes :

?mean
help("mean")

L’utilisation du raccourci ? ne fonctionne pas pour certains opérateurs comme *. Dans ce cas on pourra utiliser ?'*' ou bien simplement help("*").

Sous RStudio, le fichier d’aide associé apparaitra dans le quadrant inférieur droit sous l’onglet Help.

Onglet Help de RStudio
Onglet Help de RStudio

Cette page décrit (en anglais) la fonction, ses arguments, son résultat, le tout accompagné de diverses notes, références et exemples. Ces pages d’aide contiennent à peu près tout ce que vous pourrez chercher à savoir, mais elles ne sont pas toujours d’une lecture aisée.

Un autre cas très courant dans R est de ne pas se souvenir ou de ne pas connaître le nom de la fonction effectuant une tâche donnée. Dans ce cas on se reportera aux différentes manières de trouver de l’aide décrites dans le chapitre Où trouver de l’aide ?.

Interprétation des arguments

Prenons l’exemple de la fonction format dont la version de base permet de mettre en forme un nombre. Affichons le fichier d’aide associé.

?format

La section Usage présente les arguments de cette fonction et leur valeur par défaut :

format(x, trim = FALSE, digits = NULL, nsmall = 0L,
       justify = c("left", "right", "centre", "none"),
       width = NULL, na.encode = TRUE, scientific = NA,
       big.mark = "",   big.interval = 3L,
       small.mark = "", small.interval = 5L,
       decimal.mark = ".", zero.print = NULL,
       drop0trailing = FALSE, ...)

Regardons ce que cette fonction peut faire. Passons-lui un vecteur avec deux nombres :

format(c(12.3, 5678))
[1] "  12.3" "5678.0"

Elle renvoie un vecteur de chaînes de caractères. Le nombre de décimales a été harmonisé et des espaces ont été ajoutés au début du premier nombre afin que l’ensemble des valeurs soient alignées vers la droite.

L’argument trim permet de supprimer les espaces ajoutés en début de chaîne.

format(c(12.3, 5678), TRUE)
[1] "12.3"   "5678.0"

Dans le cas présent, nous avons saisi les arguments de la fonction sans les nommer. Dès lors, R considère l’ordre dans lesquels nous avons saisi les arguments, ordre qui correspond à celui du fichier d’aide. Il a dès lors considéré que c(12.3, 5678) correspond à la valeur attribuée à x et que TRUE est la valeur attribuée à trim.

L’argument nsmall permet d’indiquer le nombre minimum de décimales que l’on souhaite afficher. Il est en quatrième position. Dès lors, pour pouvoir le renseigner avec des arguments non nommés, il faut fournir également une valeur pour le troisième argument digits.

format(c(12.3, 5678), TRUE, NULL, 2)
[1] "12.30"   "5678.00"

Ce n’est pas forcément ce qu’il y a de plus pratique. D’où l’intérêt des arguments nommés. En précisant nsmall = dans l’appel de la fonction, on pourra indiquer que l’on souhaite modifier spécifiquement cet argument. Lorsque l’on utilise des arguments non nommés, l’ordre n’importe plus puisque R sera en capacité de reconnaître ses petits.

format(nsmall = 2, x = c(12.3, 5678))
[1] "  12.30" "5678.00"

À l’usage, on aura le plus souvent recours à une combinaison d’arguments non nommés et d’arguments nommés. On indiquera les premiers arguments (qui correspondent en général aux données de départ) sans les nommer et on précisera les options souhaitées avec des arguments nommés. Par exemple, pour un affichage à la française :

format(c(12.3, 5678), decimal.mark = ",", big.mark = " ")
[1] "   12,3" "5 678,0"

Lorsque l’on regarde la section Usage du fichier d’aide, il apparait que certains arguments, suivi par le symbole =, ont une valeur par défaut. Il n’est donc pas nécessaire de les inclure dans l’appel de la fonction, auquel cas la valeur pas défaut sera prise en compte. Par contre, d’autres arguments, ici x, n’ont pas de valeur par défaut et il est donc nécessaire de fournir systématiquement une valeur.

format(decimal.mark = ",")
Error in format.default(decimal.mark = ","): l'argument "x" est manquant, avec aucune valeur par défaut

Enfin, pour certaines fonctions, on verra parfois apparaître le symbole ... Ce dernier correspond à un nombre indéterminé d’arguments. Il peut s’agir, comme dans le cas de format d’arguments additionnels qui seront utilisés dans certains cas de figure, ou bien d’arguments qui seront transmis à une fonction secondaire appelée par la fonction principale, ou encore, comme pour le cas de la fonction c, de la possibilité de saisir un nombre indéfini de données sources.

Autocomplétion

RStudio fournit un outil bien pratique appelé autocomplétion3. Saisissez les premières lettres d’une fonction, par exemple me puis appuyez sur la touche Tabulation. RStudio affichera la liste des fonctions dont le nom commence par me ainsi qu’un court descriptif de chacune. Un appui sur la touche Entrée provoquera la saisie du nom complet de la fonction choisie.

Auto-complétion sous RStudio
Auto-complétion sous RStudio

À l’intérieur des parenthèses d’une fonction, vous pouvez utiliser l’autocomplétion pour retrouver un argument de cette fonction.

Vous pouvez également utiliser l’autocomplétion pour retrouver le nom d’un objet que vous avez précédemment créé.

Pour plus de détails, voir la documentation officielle de RStudio (https://support.rstudio.com/hc/en-us/articles/205273297-Code-Completion).


  1. La présence du [1] en début de ligne sera expliquée par la suite dans la section sur les vecteurs.

  2. c est l’abbréviation de combine. Le nom de cette fonction est très court car on l’utilise très souvent.

  3. En bon français, il faudrait dire complètement automatique.

Premier travail avec des données

Ce chapitre est inspiré de la section Premier travail avec les données du support de cours Introduction à R réalisé par Julien Barnier.

Regrouper les commandes dans des scripts

Jusqu’à maintenant nous avons utilisé uniquement la console pour communiquer avec R via l’invite de commandes. Le principal problème de ce mode d’interaction est qu’une fois qu’une commande est tapée, elle est pour ainsi dire « perdue », c’est-à-dire qu’on doit la saisir à nouveau si on veut l’exécuter une seconde fois. L’utilisation de la console est donc restreinte aux petites commandes « jetables », le plus souvent utilisées comme test.

La plupart du temps, les commandes seront stockées dans un fichier à part, que l’on pourra facilement ouvrir, éditer et exécuter en tout ou partie si besoin. On appelle en général ce type de fichier un script.

Pour comprendre comment cela fonctionne, dans RStudio cliquez sur l’icône en haut à gauche représentant un fichier avec un signe plus vert, puis choisissez R script.

Créer un nouveau script R dans RStudio
Créer un nouveau script R dans RStudio

Un nouvel onglet apparaît dans le quadrant supérieur gauche.

Onglet d’un script R dans RStudio
Onglet d’un script R dans RStudio

Nous pouvons désormais y saisir des commandes. Par exemple, tapez sur la première ligne la commande suivante : 2 + 2. Ensuite, cliquez sur l’icône Run (en haut à droite de l’onglet du script) ou bien pressez simulatément les touches CTRL et Entrée1.

Les lignes suivantes ont dû faire leur apparition dans la console :

2 + 2
[1] 4

Voici donc comment soumettre rapidement à R les commandes saisies dans votre fichier. Vous pouvez désormais l’enregistrer, l’ouvrir plus tard, et en exécuter tout ou partie. À noter que vous avez plusieurs possibilités pour soumettre des commandes à R :

  • vous pouvez exécuter la ligne sur laquelle se trouve votre curseur en cliquant sur Run ou en pressant simulatément les touches CTRL et Entrée ;
  • vous pouvez sélectionner plusieurs lignes contenant des commandes et les exécuter toutes en une seule fois exactement de la même manière ;
  • vous pouvez exécuter d’un coup l’intégralité de votre fichier en cliquant sur l’icône Source.

La plupart du travail sous R consistera donc à éditer un ou plusieurs fichiers de commandes et à envoyer régulièrement les commandes saisies à R en utilisant les raccourcis clavier ad hoc.

Pour plus d’information sur l’utilisation des scripts R dans RStudio, voir (en anglais) : https://support.rstudio.com/hc/en-us/articles/200484448-Editing-and-Executing-Code.

Quand vous enregistrez un script sous RStudio, il est possible qu’il vous demande de choisir un type d’encodage des caractères (Choose Encoding). Si tel est le cas, utilisez de préférence UTF-8.

Ajouter des commentaires

Un commentaire est une ligne ou une portion de ligne qui sera ignorée par R. Ceci signifie qu’on peut y écrire ce qu’on veut et qu’on va les utiliser pour ajouter tout un tas de commentaires à notre code permettant de décrire les différentes étapes du travail, les choses à se rappeler, les questions en suspens, etc.

Un commentaire sous R commence par un ou plusieurs symboles # (qui s’obtient avec les touches Alt Gr et 3 sur les claviers de type PC). Tout ce qui suit ce symbole jusqu’à la fin de la ligne est considéré comme un commentaire. On peut créer une ligne entière de commentaire en la faisant débuter par ##. Par exemple :

## Tableau croisé de la CSP par le nombre de livres lus.
## Attention au nombre de non réponses !

On peut aussi créer des commentaires pour une ligne en cours :

x <- 2 # On met 2 dans x, parce qu'il le vaut bien

Dans tous les cas, il est très important de documenter ses fichiers R au fur et à mesure, faute de quoi on risque de ne plus y comprendre grand chose si on les reprend ne serait-ce que quelques semaines plus tard.

Avec RStudio, vous pouvez également utiliser les commentaires pour créer des sections au sein de votre script et naviguer plus rapidement. Il suffit de faire suivre une ligne de commentaires d’au moins 4 signes moins (----). Par exemple, si vous saisissez ceci dans votre script :

## Créer les objets ----

x <- 2
y <- 5

## Calculs ----

x + y

Vous verrez apparaître en bas à gauche de la fenêtre du script un symbole dièse orange. Si vous cliquez dessus, un menu de navigation s’affichera vous permettant de vous déplacez rapidement au sein de votre script. Pour plus d’information, voir la documentation de RStudio (en anglais) : https://support.rstudio.com/hc/en-us/articles/200484568-Code-Folding-and-Sections.

Les sections peuvent également être facilement créées avec le raccourci clavier CTRL + SHIFT + R.

Navigation rapide dans les scripts sous RStudio
Navigation rapide dans les scripts sous RStudio

Note : on remarquera au passage que le titre de l’onglet est affiché en rouge et suivi d’une astérisque (*), nous indiquant ainsi qu’il y a des modifications non enregistrées dans notre fichier.

Tableaux de données

Dans cette partie nous allons utiliser un jeu de données inclus dans l’extension questionr. L’installation d’extension est décrite dans le chapitre Extensions.

Le jeu de données en question est un extrait de l’enquête Histoire de vie réalisée par l’INSEE en 2003. Il contient 2000 individus et 20 variables. Pour pouvoir utiliser ces données, il faut d’abord charger l’extension questionr (après l’avoir installée, bien entendu). Le chargement d’une extension en mémoire se fait à l’aide de la fonction library. Sous RStudio, vous pouvez également charger une extension en allant dans l’onglet Packages du quadrant inférieur droit qui liste l’ensemble des packages disponibles et en cliquant la case à cocher située à gauche du nom du package désiré.

library(questionr)

Puis nous allons indiquer à R que nous souhaitons accéder au jeu de données hdv2003 à l’aide de la fonction data :

data(hdv2003)

Bien. Et maintenant, elles sont où mes données ? Et bien elles se trouvent dans un objet nommé hdv2003 désormais chargé en mémoire et accessible directement. D’ailleurs, cet objet est maintenant visible dans l’onglet Environment du quadrant supérieur droit.

Essayons de taper son nom à l’invite de commande :

hdv2003

Le résultat (non reproduit ici) ne ressemble pas forcément à grand-chose… Il faut se rappeler que par défaut, lorsqu’on lui fournit seulement un nom d’objet, R essaye de l’afficher de la manière la meilleure (ou la moins pire) possible. La réponse à la commande hdv2003 n’est donc rien moins que l’affichage des données brutes contenues dans cet objet.

Ce qui signifie donc que l’intégralité de notre jeu de données est inclus dans l’objet nommé hdv2003 ! En effet, dans R, un objet peut très bien contenir un simple nombre, un vecteur ou bien le résultat d’une enquête tout entier. Dans ce cas, les objets sont appelés des data frames, ou tableaux de données. Ils peuvent être manipulés comme tout autre objet. Par exemple :

d <- hdv2003

va entraîner la copie de l’ensemble de nos données dans un nouvel objet nommé d, ce qui peut paraître parfaitement inutile mais a en fait l’avantage de fournir un objet avec un nom beaucoup plus court, ce qui diminuera la quantité de texte à saisir par la suite.

Résumons

Comme nous avons désormais décidé de saisir nos commandes dans un script et non plus directement dans la console, les premières lignes de notre fichier de travail sur les données de l’enquête Histoire de vie pourraient donc ressembler à ceci :

## Chargement des extensions nécessaires ----
library(questionr)
## Jeu de données hdv2003 ----
data(hdv2003)
d <- hdv2003

Inspection visuelle des données

La particularité de R par rapport à d’autres logiciels comme Modalisa ou SPSS est de ne pas proposer, par défaut, de vue des données sous forme de tableau. Ceci peut parfois être un peu déstabilisant dans les premiers temps d’utilisation, même si l’on perd vite l’habitude et qu’on finit par se rendre compte que « voir » les données n’est pas forcément un gage de productivité ou de rigueur dans le traitement.

Néanmoins, R propose une interface permettant de visualiser le contenu d’un tableau de données à l’aide de la fonction View :

View(d)

Sous RStudio, on peut aussi afficher la visionneusee (viewer) en cliquant sur la petite icône en forme de tableau située à droite de la ligne d’un tableau de données dans l’onglet Environment du quadrant supérieur droit (cf. figure ci-après).

Icône pour afficher une vue du contenu d’un tableau
Icône pour afficher une vue du contenu d’un tableau

Dans tous les cas, RStudio lancera le viewer dans un onglet dédié dans le quadrant supérieur gauche. Le visualiseur de RStudio est plus avancé que celui-de base fournit par R. Il est possible de trier les données selon une variable en cliquant sur le nom de cette dernière. Il y a également un champs de recherche et un bouton Filter donnant accès à des options de filtrage avancées.

La visionneuse de données de RStudio
La visionneuse de données de RStudio

Structure du tableau

Avant de travailler sur les données, nous allons essayer de comprendre comment elles sont structurées. Lors de l’import de données depuis un autre logiciel (que nous aborderons dans un autre chapitre), il s’agira souvent de vérifier que l’importation s’est bien déroulée.

Nous avons déjà vu qu’un tableau de données est organisé en lignes et en colonnes, les lignes correspondant aux observations et les colonnes aux variables. Les fonctions nrow, ncol et dim donnent respectivement le nombre de lignes, le nombre de colonnes et les dimensions de notre tableau. Nous pouvons donc d’ores et déjà vérifier que nous avons bien 2000 lignes et 20 colonnes :

nrow(d)
[1] 2000
ncol(d)
[1] 20
dim(d)
[1] 2000   20

La fonction names donne les noms des colonnes de notre tableau, c’est-à-dire les noms des variables :

names(d)
 [1] "id"            "age"           "sexe"         
 [4] "nivetud"       "poids"         "occup"        
 [7] "qualif"        "freres.soeurs" "clso"         
[10] "relig"         "trav.imp"      "trav.satisf"  
[13] "hard.rock"     "lecture.bd"    "peche.chasse" 
[16] "cuisine"       "bricol"        "cinema"       
[19] "sport"         "heures.tv"    

Accéder aux variables

d représente donc l’ensemble de notre tableau de données. Nous avons vu que si l’on saisit simplement d à l’invite de commandes, on obtient un affichage du tableau en question. Mais comment accéder aux variables, c’est à dire aux colonnes de notre tableau ?

La réponse est simple : on utilise le nom de l’objet, suivi de l’opérateur $, suivi du nom de la variable, comme ceci :

d$sexe

Au regard du résultat (non reproduit ici), on constate alors que R a bien accédé au contenu de notre variable sexe du tableau d et a affiché son contenu, c’est-à-dire l’ensemble des valeurs prises par la variable.

Les fonctions head et tail permettent d’afficher seulement les premières (respectivement les dernières) valeurs prises par la variable. On peut leur passer en argument le nombre d’éléments à afficher :

head(d$nivetud)
[1] Enseignement superieur y compris technique superieur
[2] <NA>                                                
[3] Derniere annee d'etudes primaires                   
[4] Enseignement superieur y compris technique superieur
[5] Derniere annee d'etudes primaires                   
[6] Enseignement technique ou professionnel court       
8 Levels: N'a jamais fait d'etudes ...
tail(d$age, 10)
 [1] 52 42 50 41 46 45 46 24 24 66

À noter que ces fonctions marchent aussi pour afficher les lignes du tableau d :

head(d, 2)

La fonction str

La fonction str est plus complète que names. Elle liste les différentes variables, indique leur type et donne le cas échéant des informations supplémentaires ainsi qu’un échantillon des premières valeurs prises par cette variable :

str(d)
'data.frame':   2000 obs. of  20 variables:
 $ id           : int  1 2 3 4 5 6 7 8 9 10 ...
 $ age          : int  28 23 59 34 71 35 60 47 20 28 ...
 $ sexe         : Factor w/ 2 levels "Homme","Femme": 2 2 1 1 2 2 2 1 2 1 ...
 $ nivetud      : Factor w/ 8 levels "N'a jamais fait d'etudes",..: 8 NA 3 8 3 6 3 6 NA 7 ...
 $ poids        : num  2634 9738 3994 5732 4329 ...
 $ occup        : Factor w/ 7 levels "Exerce une profession",..: 1 3 1 1 4 1 6 1 3 1 ...
 $ qualif       : Factor w/ 7 levels "Ouvrier specialise",..: 6 NA 3 3 6 6 2 2 NA 7 ...
 $ freres.soeurs: int  8 2 2 1 0 5 1 5 4 2 ...
 $ clso         : Factor w/ 3 levels "Oui","Non","Ne sait pas": 1 1 2 2 1 2 1 2 1 2 ...
 $ relig        : Factor w/ 6 levels "Pratiquant regulier",..: 4 4 4 3 1 4 3 4 3 2 ...
 $ trav.imp     : Factor w/ 4 levels "Le plus important",..: 4 NA 2 3 NA 1 NA 4 NA 3 ...
 $ trav.satisf  : Factor w/ 3 levels "Satisfaction",..: 2 NA 3 1 NA 3 NA 2 NA 1 ...
 $ hard.rock    : Factor w/ 2 levels "Non","Oui": 1 1 1 1 1 1 1 1 1 1 ...
 $ lecture.bd   : Factor w/ 2 levels "Non","Oui": 1 1 1 1 1 1 1 1 1 1 ...
 $ peche.chasse : Factor w/ 2 levels "Non","Oui": 1 1 1 1 1 1 2 2 1 1 ...
 $ cuisine      : Factor w/ 2 levels "Non","Oui": 2 1 1 2 1 1 2 2 1 1 ...
 $ bricol       : Factor w/ 2 levels "Non","Oui": 1 1 1 2 1 1 1 2 1 1 ...
 $ cinema       : Factor w/ 2 levels "Non","Oui": 1 2 1 2 1 2 1 1 2 2 ...
 $ sport        : Factor w/ 2 levels "Non","Oui": 1 2 2 2 1 2 1 1 1 2 ...
 $ heures.tv    : num  0 1 0 2 3 2 2.9 1 2 2 ...

La première ligne nous informe qu’il s’agit bien d’un tableau de données avec 2000 observations et 20 variables. Vient ensuite la liste des variables. La première se nomme id et est de type entier (int). La seconde se nomme age et est de type numérique. La troisième se nomme sexe, il s’agit d’un facteur (factor).

Un facteur est une variable pouvant prendre un nombre limité de modalités (levels). Ici notre variable a deux modalités possibles : « Homme » et « Femme ». Ce type de variable est décrit plus en détail dans le chapitre sur la manipulation de données.

La fonction str est essentielle à connaître et peut s’appliquer à n’importe quel type d’objet. C’est un excellent moyen de connaître en détail la structure d’un objet. Cependant, les résultats peuvent être parfois trop détaillés et on lui priviligiera dans certains cas la fonction describe que l’on abordera dans les prochains chapitres, cependant moins générique puisque ne s’appliquant qu’à des tableaux de données et à des vecteurs, tandis que str peut s’appliquer à absolument tout objet, y compris des fonctions.

describe(d)
d 

 20  Variables      2000  Observations
------------------------------------------------------------
id 
       n  missing distinct     Info     Mean      Gmd 
    2000        0     2000        1     1000      667 
     .05      .10      .25      .50      .75      .90 
   101.0    200.9    500.8   1000.5   1500.2   1800.1 
     .95 
  1900.0 

lowest :    1    2    3    4    5, highest: 1996 1997 1998 1999 2000
------------------------------------------------------------
age 
       n  missing distinct     Info     Mean      Gmd 
    2000        0       78        1    48.16     19.4 
     .05      .10      .25      .50      .75      .90 
      22       26       35       48       60       72 
     .95 
      77 

lowest : 18 19 20 21 22, highest: 91 92 93 96 97
------------------------------------------------------------
sexe 
       n  missing distinct 
    2000        0        2 
                      
Value      Homme Femme
Frequency    899  1101
Proportion  0.45  0.55
------------------------------------------------------------
nivetud 
       n  missing distinct 
    1888      112        8 

lowest : N'a jamais fait d'etudes                                        A arrete ses etudes, avant la derniere annee d'etudes primaires Derniere annee d'etudes primaires                               1er cycle                                                       2eme cycle                                                     
highest: 1er cycle                                                       2eme cycle                                                      Enseignement technique ou professionnel court                   Enseignement technique ou professionnel long                    Enseignement superieur y compris technique superieur           
------------------------------------------------------------
poids 
       n  missing distinct     Info     Mean      Gmd 
    2000        0     1877        1     5536     4553 
     .05      .10      .25      .50      .75      .90 
   799.8   1161.7   2221.8   4631.2   7626.5  10819.0 
     .95 
 13647.9 

lowest :    78.08    92.68    92.94   127.90   153.01
highest: 27195.84 29548.79 29570.79 29657.94 31092.14
------------------------------------------------------------
occup 
       n  missing distinct 
    2000        0        7 

lowest : Exerce une profession Chomeur               Etudiant, eleve       Retraite              Retire des affaires  
highest: Etudiant, eleve       Retraite              Retire des affaires   Au foyer              Autre inactif        

Exerce une profession (1049, 0.524), Chomeur (134, 0.067),
Etudiant, eleve (94, 0.047), Retraite (392, 0.196), Retire
des affaires (77, 0.038), Au foyer (171, 0.086), Autre
inactif (83, 0.042)
------------------------------------------------------------
qualif 
       n  missing distinct 
    1653      347        7 

lowest : Ouvrier specialise       Ouvrier qualifie         Technicien               Profession intermediaire Cadre                   
highest: Technicien               Profession intermediaire Cadre                    Employe                  Autre                   

Ouvrier specialise (203, 0.123), Ouvrier qualifie (292,
0.177), Technicien (86, 0.052), Profession intermediaire
(160, 0.097), Cadre (260, 0.157), Employe (594, 0.359),
Autre (58, 0.035)
------------------------------------------------------------
freres.soeurs 
       n  missing distinct     Info     Mean      Gmd 
    2000        0       19    0.977    3.283     2.87 
     .05      .10      .25      .50      .75      .90 
       0        1        1        2        5        7 
     .95 
       9 

lowest :  0  1  2  3  4, highest: 14 15 16 18 22

0 (167, 0.084), 1 (407, 0.203), 2 (427, 0.214), 3 (284,
0.142), 4 (210, 0.105), 5 (151, 0.076), 6 (99, 0.050), 7
(94, 0.047), 8 (52, 0.026), 9 (37, 0.018), 10 (21, 0.011),
11 (21, 0.011), 12 (8, 0.004), 13 (10, 0.005), 14 (4,
0.002), 15 (4, 0.002), 16 (1, 0.000), 18 (2, 0.001), 22 (1,
0.000)
------------------------------------------------------------
clso 
       n  missing distinct 
    2000        0        3 
                                              
Value              Oui         Non Ne sait pas
Frequency          936        1037          27
Proportion       0.468       0.518       0.014
------------------------------------------------------------
relig 
       n  missing distinct 
    2000        0        6 

lowest : Pratiquant regulier         Pratiquant occasionnel      Appartenance sans pratique  Ni croyance ni appartenance Rejet                      
highest: Pratiquant occasionnel      Appartenance sans pratique  Ni croyance ni appartenance Rejet                       NSP ou NVPR                

Pratiquant regulier (266, 0.133), Pratiquant occasionnel
(442, 0.221), Appartenance sans pratique (760, 0.380), Ni
croyance ni appartenance (399, 0.200), Rejet (93, 0.046),
NSP ou NVPR (40, 0.020)
------------------------------------------------------------
trav.imp 
       n  missing distinct 
    1048      952        4 

Le plus important (29, 0.028), Aussi important que le reste
(259, 0.247), Moins important que le reste (708, 0.676),
Peu important (52, 0.050)
------------------------------------------------------------
trav.satisf 
       n  missing distinct 
    1048      952        3 
                                                       
Value        Satisfaction Insatisfaction      Equilibre
Frequency             480            117            451
Proportion          0.458          0.112          0.430
------------------------------------------------------------
hard.rock 
       n  missing distinct 
    2000        0        2 
                      
Value        Non   Oui
Frequency   1986    14
Proportion 0.993 0.007
------------------------------------------------------------
lecture.bd 
       n  missing distinct 
    2000        0        2 
                      
Value        Non   Oui
Frequency   1953    47
Proportion 0.977 0.024
------------------------------------------------------------
peche.chasse 
       n  missing distinct 
    2000        0        2 
                      
Value        Non   Oui
Frequency   1776   224
Proportion 0.888 0.112
------------------------------------------------------------
cuisine 
       n  missing distinct 
    2000        0        2 
                      
Value        Non   Oui
Frequency   1119   881
Proportion 0.559 0.440
------------------------------------------------------------
bricol 
       n  missing distinct 
    2000        0        2 
                      
Value        Non   Oui
Frequency   1147   853
Proportion 0.574 0.426
------------------------------------------------------------
cinema 
       n  missing distinct 
    2000        0        2 
                      
Value        Non   Oui
Frequency   1174   826
Proportion 0.587 0.413
------------------------------------------------------------
sport 
       n  missing distinct 
    2000        0        2 
                      
Value        Non   Oui
Frequency   1277   723
Proportion 0.638 0.362
------------------------------------------------------------
heures.tv 
       n  missing distinct     Info     Mean      Gmd 
    1995        5       29    0.972    2.247    1.877 
     .05      .10      .25      .50      .75      .90 
       0        0        1        2        3        4 
     .95 
       5 

lowest :  0.0  0.1  0.2  0.3  0.4, highest:  8.0  9.0 10.0 11.0 12.0
------------------------------------------------------------

Quelques calculs simples

Maintenant que nous savons accéder aux variables, effectuons quelques calculs simples comme la moyenne, la médiane, le minimum et le maximum, à l’aide des fonctions mean, median, min et max.

mean(d$age)
[1] 48.16
median(d$age)
[1] 48
min(d$age)
[1] 18
max(d$age)
[1] 97

Au sens strict, il ne s’agit pas d’un véritable âge moyen puisqu’il faudrait ajouter 0,5 à cette valeur calculée, un âge moyen se calculant à partir d’âges exacts et non à partir d’âges révolus. Voir le chapitre Calculer un âge.

On peut aussi très facilement obtenir un tri à plat à l’aide la fonction table :

table(d$qualif)

      Ouvrier specialise         Ouvrier qualifie 
                     203                      292 
              Technicien Profession intermediaire 
                      86                      160 
                   Cadre                  Employe 
                     260                      594 
                   Autre 
                      58 

La fonction summary, bien pratique, permet d’avoir une vue résumée d’une variable. Elle s’applique à tout type d’objets (y compris un tableau de données entier) et s’adapte à celui-ci.

summary(d$age)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   18.0    35.0    48.0    48.2    60.0    97.0 
summary(d$qualif)
      Ouvrier specialise         Ouvrier qualifie 
                     203                      292 
              Technicien Profession intermediaire 
                      86                      160 
                   Cadre                  Employe 
                     260                      594 
                   Autre                     NA's 
                      58                      347 
summary(d)
       id            age          sexe     
 Min.   :   1   Min.   :18.0   Homme: 899  
 1st Qu.: 501   1st Qu.:35.0   Femme:1101  
 Median :1000   Median :48.0               
 Mean   :1000   Mean   :48.2               
 3rd Qu.:1500   3rd Qu.:60.0               
 Max.   :2000   Max.   :97.0               
                                           
                                                 nivetud   
 Enseignement technique ou professionnel court       :463  
 Enseignement superieur y compris technique superieur:441  
 Derniere annee d'etudes primaires                   :341  
 1er cycle                                           :204  
 2eme cycle                                          :183  
 (Other)                                             :256  
 NA's                                                :112  
     poids                         occup     
 Min.   :   78   Exerce une profession:1049  
 1st Qu.: 2222   Chomeur              : 134  
 Median : 4631   Etudiant, eleve      :  94  
 Mean   : 5536   Retraite             : 392  
 3rd Qu.: 7627   Retire des affaires  :  77  
 Max.   :31092   Au foyer             : 171  
                 Autre inactif        :  83  
                      qualif    freres.soeurs  
 Employe                 :594   Min.   : 0.00  
 Ouvrier qualifie        :292   1st Qu.: 1.00  
 Cadre                   :260   Median : 2.00  
 Ouvrier specialise      :203   Mean   : 3.28  
 Profession intermediaire:160   3rd Qu.: 5.00  
 (Other)                 :144   Max.   :22.00  
 NA's                    :347                  
          clso                              relig    
 Oui        : 936   Pratiquant regulier        :266  
 Non        :1037   Pratiquant occasionnel     :442  
 Ne sait pas:  27   Appartenance sans pratique :760  
                    Ni croyance ni appartenance:399  
                    Rejet                      : 93  
                    NSP ou NVPR                : 40  
                                                     
                         trav.imp           trav.satisf 
 Le plus important           : 29   Satisfaction  :480  
 Aussi important que le reste:259   Insatisfaction:117  
 Moins important que le reste:708   Equilibre     :451  
 Peu important               : 52   NA's          :952  
 NA's                        :952                       
                                                        
                                                        
 hard.rock  lecture.bd peche.chasse cuisine    bricol    
 Non:1986   Non:1953   Non:1776     Non:1119   Non:1147  
 Oui:  14   Oui:  47   Oui: 224     Oui: 881   Oui: 853  
                                                         
                                                         
                                                         
                                                         
                                                         
 cinema     sport        heures.tv    
 Non:1174   Non:1277   Min.   : 0.00  
 Oui: 826   Oui: 723   1st Qu.: 1.00  
                       Median : 2.00  
                       Mean   : 2.25  
                       3rd Qu.: 3.00  
                       Max.   :12.00  
                       NA's   :5      

Nos premiers graphiques

R est très puissant en termes de représentations graphiques, notamment grâce à des extensions dédiées. Pour l’heure contentons-nous d’un premier essai à l’aide de la fonction générique plot.

plot(d$sexe)
Nombre d’observations par sexe

Essayons avec deux variables :

plot(d$hard.rock, d$age)
Âge des enquêtés selon qu’ils écoutent ou non du hard rock

Il semblerait bien que les amateurs de hard rock soient plus jeunes.

Et ensuite ?

Nous n’avons qu’entr’aperçu les possibilités de R. Avant de pouvoir nous lancer dans des analyses statisques, il est préférable de revenir un peu aux fondamentaux de R (les types d’objets, la syntaxe, le recodage de variables…) mais aussi comment installer des extensions, importer des données, etc. Nous vous conseillons donc de poursuivre la lecture de la section Prise en main puis de vous lancer à l’assault de la section Statistique introductive.


  1. Sous Mac OS X, on utilise les touches Pomme et Entrée.

Extensions (installation, mise à jour)

Présentation

L’installation par défaut du logiciel R contient le cœur du programme ainsi qu’un ensemble de fonctions de base fournissant un grand nombre d’outils de traitement de données et d’analyse statistiques.

R étant un logiciel libre, il bénéficie d’une forte communauté d’utilisateurs qui peuvent librement contribuer au développement du logiciel en lui ajoutant des fonctionnalités supplémentaires. Ces contributions prennent la forme d’extensions (packages en anglais) pouvant être installées par l’utilisateur et fournissant alors diverses fonctionnalités supplémentaires.

Il existe un très grand nombre d’extensions (plus de 6500 à ce jour), qui sont diffusées par un réseau baptisé CRAN (Comprehensive R Archive Network).

La liste de toutes les extensions disponibles sur CRAN est disponible ici : http://cran.r-project.org/web/packages/.

Pour faciliter un peu le repérage des extensions, il existe un ensemble de regroupements thématiques (économétrie, finance, génétique, données spatiales…) baptisés Task views : http://cran.r-project.org/web/views/.

On y trouve notamment une Task view dédiée aux sciences sociales, listant de nombreuses extensions potentiellement utiles pour les analyses statistiques dans ce champ disciplinaire : http://cran.r-project.org/web/views/SocialSciences.html.

On peut aussi citer le site Awesome R (https://awesome-r.com/) qui fournit une liste d’extensions choisies et triées par thématique.

Le tidyverse

Hadley Wickham est professeur associé à l’université de Rice et scientifique en chef à Rstudio. Il a développé de nombreux extensions pour R (plus d’une cinquantaine à ce jours) qui, pour la plupart, fonctionne de manière harmonisée entre elles. Par ailleurs, la plupart s’intègre parfaitement avec RStudio. Cet ensemble d’extenions est appelé tidyverse et est développé sur GitHub : https://github.com/tidyverse/. Une présentation plus générale du tidyverse est disponible sur le site de RStudio (https://www.rstudio.com/products/rpackages/) et sur un sité dédié (http://tidyverse.org/).

Pour certaines tâches, il peut exister plusieurs solutions / extensions différentes pour les réaliser. Dans la mesure où il n’est pas possible d’être exhaustif, nous avons fait le choix dans le cadre d’analyse-R de choisir en priorité, lorsque cela est possible, les extensions du tidyverse, en particulier haven, readr et readxl pour l’import de données, dplyr, tidyr ou reshape2 pour la manipulation de données, ggplot2 pour les graphiques, lubridate pour la gestion des dates, forcats pour la manipulation des facteurs ou encore stringr pour la manipulation de chaînes de caractères.

Il existe par ailleurs une extension homonyme tidyverse. L’installation (voir ci-dessous) de cette extension permets l’installation automatique de l’ensemble des autres extensions du tidyverse. Le chargement de cette extension avec la fonction library (voir ci-après) permets de charger en mémoire en une seule opération les principales extensions du tidyverse, à savoir ggplot2, tibble, tidyr, readr, purrr et dplyr.

Pour une présentation plus poussée, voir le chapitre consacré au tidyverse.

Installation depuis CRAN

L’installation d’une extension se fait par la fonction install.packages, à qui on fournit le nom de l’extension. Par exemple, si on souhaite installer l’extension ade4 :

install.packages("ade4", dep = TRUE)

L’option dep=TRUE indique à R de télécharger et d’installer également toutes les extensions dont l’extension choisie dépend pour son fonctionnement.

Sous RStudio, on pourra également cliquer sur Install dans l’onglet Packages du quadrant inférieur droit.

Une fois l’extension installée, elle peut être appelée depuis la console ou un fichier script avec la fonction library ou la fonction require :

library(ade4)

À partir de là, on peut utiliser les fonctions de l’extension, consulter leur page d’aide en ligne, accéder aux jeux de données qu’elle contient, etc.

Pour mettre à jour l’ensemble des extensions installées, <dfndata-index=“mise à jour, extensions”> la fonction update.packages suffit :

update.packages()

Sous RStudio, on pourra alternativement cliquer sur Update dans l’onglet Packages du quadrant inférieur droit.

Si on souhaite désinstaller une extension précédemment installée, on peut utiliser la fonction remove.packages :

remove.packages("ade4")

Il est important de bien comprendre la différence entre install.packages et library. La première va chercher les extensions sur internet et les installe en local sur le disque dur de l’ordinateur. On n’a besoin d’effectuer cette opération qu’une seule fois. La seconde lit les informations de l’extension sur le disque dur et les met à disposition de R. On a besoin de l’exécuter à chaque début de session ou de script.

Installation depuis GitHub

Certains packages sont développés sur GitHub. Dès lors, la version de développement sur GitHub peut contenir des fonctions qui ne sont pas encore disponibles dans la version stable disponible sur CRAN. Ils arrivent aussi parfois que certains packages ne soient disponibles que sur GitHub.

L’installation d’un package depuis GitHub est très facile grâce à la fonction install_github de l’extension devtools (que l’on aura préalablement installée depuis CRAN ;-) ).

Mise à jour des extensions

Il est facile de mettre à jour l’ensemble des extensions installées, soit avec la fonction, update.packages soit en cliquant sur Update dans l’onglet Packages du quadrant inférieur droit.

Introduction au tidyverse

La version originale de ce chapitre a été écrite par Julien Barnier dans le cadre de son Introduction à R et au tidyverse.

Extensions

Le terme tidyverse est une contraction de tidy (qu’on pourrait traduire par “bien rangé”) et de universe. Il s’agit en fait d’une collection d’extensions conçues pour travailler ensemble et basées sur une philosophie commune.

Elles abordent un très grand nombre d’opérations courantes dans R (la liste n’est pas exhaustive) :

  • visualisation
  • manipulation des tableaux de données
  • import/export de données
  • manipulation de variables
  • extraction de données du Web
  • programmation

Un des objectifs de ces extensions est de fournir des fonctions avec une syntaxe cohérente, qui fonctionnent bien ensemble, et qui retournent des résultats prévisibles. Elles sont en grande partie issues du travail d’Hadley Wickham, qui travaille désormais pour RStudio.

Installation

tidyverse est également le nom d’une extension qu’on peut installer de manière classique, soit via le bouton Install de l’onglet Packages de RStudio, soit en utilisant la commande :

install.packages("tidyverse")

Cette commande va en fait installer plusieurs extensions qui constituent le coeur du tidyverse, à savoir :

  • ggplot2 (visualisation)
  • dplyr (manipulation des données)
  • tidyr (remise en forme des données)
  • purrr (programmation)
  • readr (importation de données)
  • tibble (tableaux de données)
  • forcats (variables qualitatives)
  • stringr (chaînes de caractères)

De la même manière, charger l’extension avec :

library(tidyverse)

Chargera l’ensemble des extensions précédentes.

Il existe d’autres extensions qui font partie du tidyverse mais qui doivent être chargées explicitement, comme par exemple readxl (pour l’importation de données depuis des fichiers Excel).

La liste complète des extensions se trouve sur le site officiel du tidyverse.

tidy data

Le tidyverse est en partie fondé sur le concept de tidy data, développé à l’origine par Hadley Wickham dans un article de 2014 du Journal of Statistical Software.

Il s’agit d’un modèle d’organisation des données qui vise à faciliter le travail souvent long et fastidieux de nettoyage et de préparation préalable à la mise en oeuvre de méthodes d’analyse.

Les principes d’un jeu de données tidy sont les suivants :

  1. chaque variable est une colonne
  2. chaque observation est une ligne
  3. chaque type d’observation est dans une table différente

Un chapitre dédié à tidyr présente comment définir et rendre des données tidy avec l’extension tidyr.

Les extensions du tidyverse, notamment ggplot2 et dplyr, sont prévues pour fonctionner avec des données tidy.

tibbles

Une autre particularité du tidyverse est que ces extensions travaillent avec des tableaux de données au format tibble, qui est une évolution plus moderne du classique data frame du R de base. Ce format est fourni est géré par l’extension du même nom (tibble), qui fait partie du coeur du tidyverse. La plupart des fonctions des extensions du tidyverse acceptent des data frames en entrée, mais retournent un objet de classe tibble.

Contrairement aux data frames, les tibbles :

  • n’ont pas de noms de lignes (rownames)
  • autorisent des noms de colonnes invalides pour les data frames (espaces, caractères spéciaux, nombres…) 1
  • s’affichent plus intelligemment que les data frames : seules les premières lignes sont affichées, ainsi que quelques informations supplémentaires utiles (dimensions, types des colonnes…)
  • ne font pas de partial matching sur les noms de colonnes 2
  • affichent un avertissement si on essaie d’accéder à une colonne qui n’existe pas

Pour autant, les tibbles restent compatibles avec les data frames. On peut ainsi facilement convertir un data frame en tibble avec as_tibble :

library(tidyverse)
as_tibble(mtcars)
# A tibble: 32 x 12
     mpg   cyl  disp    hp  drat    wt  qsec    vs    am
   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1  21       6  160    110  3.9   2.62  16.5     0     1
 2  21       6  160    110  3.9   2.88  17.0     0     1
 3  22.8     4  108     93  3.85  2.32  18.6     1     1
 4  21.4     6  258    110  3.08  3.22  19.4     1     0
 5  18.7     8  360    175  3.15  3.44  17.0     0     0
 6  18.1     6  225    105  2.76  3.46  20.2     1     0
 7  14.3     8  360    245  3.21  3.57  15.8     0     0
 8  24.4     4  147.    62  3.69  3.19  20       1     0
 9  22.8     4  141.    95  3.92  3.15  22.9     1     0
10  19.2     6  168.   123  3.92  3.44  18.3     1     0
# ... with 22 more rows, and 3 more variables: gear <dbl>,
#   carb <dbl>, name <chr>

Si le data frame d’origine a des rownames, on peut d’abord les convertir en colonnes avec rownames_to_columns :

d <- as_tibble(rownames_to_column(mtcars))
d
# A tibble: 32 x 13
   rowname     mpg   cyl  disp    hp  drat    wt  qsec    vs
   <chr>     <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1 Mazda RX4  21       6  160    110  3.9   2.62  16.5     0
 2 Mazda RX~  21       6  160    110  3.9   2.88  17.0     0
 3 Datsun 7~  22.8     4  108     93  3.85  2.32  18.6     1
 4 Hornet 4~  21.4     6  258    110  3.08  3.22  19.4     1
 5 Hornet S~  18.7     8  360    175  3.15  3.44  17.0     0
 6 Valiant    18.1     6  225    105  2.76  3.46  20.2     1
 7 Duster 3~  14.3     8  360    245  3.21  3.57  15.8     0
 8 Merc 240D  24.4     4  147.    62  3.69  3.19  20       1
 9 Merc 230   22.8     4  141.    95  3.92  3.15  22.9     1
10 Merc 280   19.2     6  168.   123  3.92  3.44  18.3     1
# ... with 22 more rows, and 4 more variables: am <dbl>,
#   gear <dbl>, carb <dbl>, name <chr>

À l’inverse, on peut à tout moment convertir un tibble en data frame avec as.data.frame :

as.data.frame(d)
               rowname  mpg cyl  disp  hp drat    wt  qsec
1            Mazda RX4 21.0   6 160.0 110 3.90 2.620 16.46
2        Mazda RX4 Wag 21.0   6 160.0 110 3.90 2.875 17.02
3           Datsun 710 22.8   4 108.0  93 3.85 2.320 18.61
4       Hornet 4 Drive 21.4   6 258.0 110 3.08 3.215 19.44
5    Hornet Sportabout 18.7   8 360.0 175 3.15 3.440 17.02
6              Valiant 18.1   6 225.0 105 2.76 3.460 20.22
7           Duster 360 14.3   8 360.0 245 3.21 3.570 15.84
8            Merc 240D 24.4   4 146.7  62 3.69 3.190 20.00
9             Merc 230 22.8   4 140.8  95 3.92 3.150 22.90
10            Merc 280 19.2   6 167.6 123 3.92 3.440 18.30
11           Merc 280C 17.8   6 167.6 123 3.92 3.440 18.90
12          Merc 450SE 16.4   8 275.8 180 3.07 4.070 17.40
13          Merc 450SL 17.3   8 275.8 180 3.07 3.730 17.60
14         Merc 450SLC 15.2   8 275.8 180 3.07 3.780 18.00
15  Cadillac Fleetwood 10.4   8 472.0 205 2.93 5.250 17.98
16 Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82
17   Chrysler Imperial 14.7   8 440.0 230 3.23 5.345 17.42
18            Fiat 128 32.4   4  78.7  66 4.08 2.200 19.47
19         Honda Civic 30.4   4  75.7  52 4.93 1.615 18.52
20      Toyota Corolla 33.9   4  71.1  65 4.22 1.835 19.90
21       Toyota Corona 21.5   4 120.1  97 3.70 2.465 20.01
22    Dodge Challenger 15.5   8 318.0 150 2.76 3.520 16.87
23         AMC Javelin 15.2   8 304.0 150 3.15 3.435 17.30
24          Camaro Z28 13.3   8 350.0 245 3.73 3.840 15.41
25    Pontiac Firebird 19.2   8 400.0 175 3.08 3.845 17.05
26           Fiat X1-9 27.3   4  79.0  66 4.08 1.935 18.90
27       Porsche 914-2 26.0   4 120.3  91 4.43 2.140 16.70
28        Lotus Europa 30.4   4  95.1 113 3.77 1.513 16.90
29      Ford Pantera L 15.8   8 351.0 264 4.22 3.170 14.50
30        Ferrari Dino 19.7   6 145.0 175 3.62 2.770 15.50
31       Maserati Bora 15.0   8 301.0 335 3.54 3.570 14.60
32          Volvo 142E 21.4   4 121.0 109 4.11 2.780 18.60
   vs am gear carb                name
1   0  1    4    4           Mazda RX4
2   0  1    4    4       Mazda RX4 Wag
3   1  1    4    1          Datsun 710
4   1  0    3    1      Hornet 4 Drive
5   0  0    3    2   Hornet Sportabout
6   1  0    3    1             Valiant
7   0  0    3    4          Duster 360
8   1  0    4    2           Merc 240D
9   1  0    4    2            Merc 230
10  1  0    4    4            Merc 280
11  1  0    4    4           Merc 280C
12  0  0    3    3          Merc 450SE
13  0  0    3    3          Merc 450SL
14  0  0    3    3         Merc 450SLC
15  0  0    3    4  Cadillac Fleetwood
16  0  0    3    4 Lincoln Continental
17  0  0    3    4   Chrysler Imperial
18  1  1    4    1            Fiat 128
19  1  1    4    2         Honda Civic
20  1  1    4    1      Toyota Corolla
21  1  0    3    1       Toyota Corona
22  0  0    3    2    Dodge Challenger
23  0  0    3    2         AMC Javelin
24  0  0    3    4          Camaro Z28
25  0  0    3    2    Pontiac Firebird
26  1  1    4    1           Fiat X1-9
27  0  1    5    2       Porsche 914-2
28  1  1    5    2        Lotus Europa
29  0  1    5    4      Ford Pantera L
30  0  1    5    6        Ferrari Dino
31  0  1    5    8       Maserati Bora
32  1  1    4    2          Volvo 142E

Là encore, on peut convertir la colonne rowname en “vrais” rownames avec column_to_rownames :

column_to_rownames(as.data.frame(d))
                     mpg cyl  disp  hp drat    wt  qsec vs
Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0
Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0
Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1
Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1
Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0
Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1
Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0
Merc 240D           24.4   4 146.7  62 3.69 3.190 20.00  1
Merc 230            22.8   4 140.8  95 3.92 3.150 22.90  1
Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1
Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1
Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0
Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0
Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0
Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0
Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0
Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0
Fiat 128            32.4   4  78.7  66 4.08 2.200 19.47  1
Honda Civic         30.4   4  75.7  52 4.93 1.615 18.52  1
Toyota Corolla      33.9   4  71.1  65 4.22 1.835 19.90  1
Toyota Corona       21.5   4 120.1  97 3.70 2.465 20.01  1
Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0
AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0
Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0
Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0
Fiat X1-9           27.3   4  79.0  66 4.08 1.935 18.90  1
Porsche 914-2       26.0   4 120.3  91 4.43 2.140 16.70  0
Lotus Europa        30.4   4  95.1 113 3.77 1.513 16.90  1
Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0
Ferrari Dino        19.7   6 145.0 175 3.62 2.770 15.50  0
Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0
Volvo 142E          21.4   4 121.0 109 4.11 2.780 18.60  1
                    am gear carb                name
Mazda RX4            1    4    4           Mazda RX4
Mazda RX4 Wag        1    4    4       Mazda RX4 Wag
Datsun 710           1    4    1          Datsun 710
Hornet 4 Drive       0    3    1      Hornet 4 Drive
Hornet Sportabout    0    3    2   Hornet Sportabout
Valiant              0    3    1             Valiant
Duster 360           0    3    4          Duster 360
Merc 240D            0    4    2           Merc 240D
Merc 230             0    4    2            Merc 230
Merc 280             0    4    4            Merc 280
Merc 280C            0    4    4           Merc 280C
Merc 450SE           0    3    3          Merc 450SE
Merc 450SL           0    3    3          Merc 450SL
Merc 450SLC          0    3    3         Merc 450SLC
Cadillac Fleetwood   0    3    4  Cadillac Fleetwood
Lincoln Continental  0    3    4 Lincoln Continental
Chrysler Imperial    0    3    4   Chrysler Imperial
Fiat 128             1    4    1            Fiat 128
Honda Civic          1    4    2         Honda Civic
Toyota Corolla       1    4    1      Toyota Corolla
Toyota Corona        0    3    1       Toyota Corona
Dodge Challenger     0    3    2    Dodge Challenger
AMC Javelin          0    3    2         AMC Javelin
Camaro Z28           0    3    4          Camaro Z28
Pontiac Firebird     0    3    2    Pontiac Firebird
Fiat X1-9            1    4    1           Fiat X1-9
Porsche 914-2        1    5    2       Porsche 914-2
Lotus Europa         1    5    2        Lotus Europa
Ford Pantera L       1    5    4      Ford Pantera L
Ferrari Dino         1    5    6        Ferrari Dino
Maserati Bora        1    5    8       Maserati Bora
Volvo 142E           1    4    2          Volvo 142E

Les deux fonctions column_to_rownames et rownames_to_column acceptent un argument supplémentaire var qui permet d’indiquer un nom de colonne autre que le nom rowname utilisé par défaut pour créer ou identifier la colonne contenant les noms de lignes.


  1. Quand on veut utiliser des noms de ce type, on doit les entourer avec des backticks (`)

  2. Dans R de base, si une table d contient une colonne qualif, d$qual retournera cette colonne.

Vecteurs, indexation et assignation

Nous allons reprendre plusieurs éléments de base du langage R que nous avons déjà abordés mais de manière plus formelle. Une bonne compréhension des bases du langage, bien qu’un peu ardue de prime abord, permet de comprendre le sens des commandes qu’on utilise et de pleinement exploiter la puissance que R offre en matière de manipulation de données.

Dans ce chapitre, nous reviendrons sur les vecteurs, tandis que les listes et les tableaux de données seront abordés dans un chapitre dédié.

Présentation des vecteurs

Les vecteurs sont l’un des objets de base de R et correspondent à une liste de valeurs. Leurs propriétés fondamentales sont :

  • les vecteurs sont unidimensionnels (i.e. ce sont des objets à une seule dimension, à la différence d’une matrice par exemple) ;
  • toutes les valeurs d’un vecteur sont d’un seul et même type ;
  • les vecteurs ont une longueur qui correspond au nombre de valeurs contenues dans le vecteur.

Les principaux types de vecteurs

Dans R, il existe quatre types fondamentaux de vecteurs :

  • les nombres réels (c’est-à-dire les nombres décimaux que nous utilisons au quotidien),
  • les nombres entiers,
  • les chaînes de caractères (qui correspondent à du texte) et
  • les valeurs logiques ou valeurs booléennes, à savoir vrai ou faux.

Pour connaître la nature d’un objet, le plus simple est d’utiliser la fonction class. Par exemple :

class(12.5)
[1] "numeric"

La réponse "numeric" nous indique qu’il s’agit d’un nombre réel. Parfois, vous pourrez rencontrer le terme "double" qui désigne également les nombres réels. Notez que R étant anglophone, la décimale est indiquée avec un point (.) et non avec une virgule comme c’est l’usage en français.

Essayons avec un nombre entier :

class(3)
[1] "numeric"

Sous R, lorsqu’on tape un nombre sans autre précision, il est considéré par défaut comme un nombre réel. Pour indiquer spécifiquement qu’on veut un nombre entier, il faut rajouter le suffixe L :

class(3L)
[1] "integer"

Au quotidien, il arrive rarement d’avoir à utiliser ce suffixe, mais il est toujours bon de le connaître au cas où vous le rencontriez dans des manuels ou des exemples de code.

Pour saisir une chaîne de caractères, on aura recours aux doubles guillemets droits (") :

class("abc")
[1] "character"

Il est également possible d’utiliser des guillemets simples ('), dès lors qu’on utilise bien le même type de guillemets pour indiquer le début et la fin de la chaîne de caractères (par exemple 'abc').

Enfin, les valeurs logiques s’indiquent avec TRUE pour vrai et FALSE pour faux. Il est aussi possible d’utiliser les raccourcis T et F. Attention à bien utiliser les majuscules, R étant sensible à la casse.

class(TRUE)
[1] "logical"

En résumé, les classes R des quatre types fondamentaux de vecteur sont :

Exemple Classe R Type
5L integer nombre entier
3.14 numeric nombre réel
"abcd" character chaîne de caractères
TRUE logical booléenne

En plus des types de base, il existe de nombreuses autres classes de vecteurs dans R que nous aborderons ultérieurement dans d’autres chapitres. Les plus courantes sont :

Classe R Type
factor facteur
labelled vecteur labellisé
Date date
POSIXct date et heure

Création

La fonction c

Pour créer un vecteur, on utilisera la fonction c, la lettre c étant un raccourci du mot anglais combine puisque cette fonction permet de combiner des valeurs individuelles dans un vecteur unique. Il suffit de lui passer la liste des valeurs à combiner :

taille <- c(1.88, 1.65, 1.92, 1.76)
taille
[1] 1.88 1.65 1.92 1.76
class(taille)
[1] "numeric"
sexe <- c("h", "f", "h", "f")
sexe
[1] "h" "f" "h" "f"
class(sexe)
[1] "character"
urbain <- c(TRUE, TRUE, FALSE, FALSE)
urbain
[1]  TRUE  TRUE FALSE FALSE
class(urbain)
[1] "logical"

Nous l’avons vu, toutes les valeurs d’un vecteur doivent obligatoirement être du même type. Dès lors, si on essaie de combiner des valeurs de différents types, R essaiera de les convertir au mieux. Par exemple :

x <- c(2L, 3.14, "a")
x
[1] "2"    "3.14" "a"   
class(x)
[1] "character"

Dans le cas présent, toutes les valeurs ont été converties en chaînes de caractères.

La fonction rep

Dans certaines situations, on peut avoir besoin de créer un vecteur d’une certaine longueur mais dont toutes les valeurs sont identiques. Cela se réalise facilement avec rep à qui on indiquera la valeur à répéter puis le nombre de répétitions :

rep(2, 10)
 [1] 2 2 2 2 2 2 2 2 2 2

On peut aussi lui indiquer plusieurs valeurs qui seront alors répétées en boucle :

rep(c("a", "b"), 3)
[1] "a" "b" "a" "b" "a" "b"

La fonction seq

Dans d’autres situations, on peut avoir besoin de créer un vecteur contenant une suite de valeurs, ce qui se réalise aisément avec seq à qui on précisera les arguments from (point de départ), to (point d’arrivée) et by (pas). Quelques exemples valent mieux qu’un long discours :

seq(1, 10)
 [1]  1  2  3  4  5  6  7  8  9 10
seq(5, 17, by = 2)
[1]  5  7  9 11 13 15 17
seq(10, 0)
 [1] 10  9  8  7  6  5  4  3  2  1  0
seq(100, 10, by = -10)
 [1] 100  90  80  70  60  50  40  30  20  10
seq(1.23, 5.67, by = 0.33)
 [1] 1.23 1.56 1.89 2.22 2.55 2.88 3.21 3.54 3.87 4.20 4.53
[12] 4.86 5.19 5.52

L’opérateur :

L’opérateur : est un raccourci de la fonction seq pour créer une suite de nombres entiers. Il s’utilise ainsi :

1:5
[1] 1 2 3 4 5
24:32
[1] 24 25 26 27 28 29 30 31 32
55:43
 [1] 55 54 53 52 51 50 49 48 47 46 45 44 43

Nous verrons un peu plus loin que ce raccourci est fort pratique.

Longueur d’un vecteur

Un vecteur dispose donc d’une longueur qui correspond au nombre de valeurs qui le composent. Elle s’obtient avec length :

length(taille)
[1] 4
length(c("a", "b"))
[1] 2

Il est possible de faire un vecteur de longueur nulle avec c(). Bien évidemment sa longueur est zéro.

length(c())
[1] 0

Quelques vecteurs remarquables

R fournit quelques vecteurs particuliers qui sont directement accessibles :

  • LETTERS : les 26 lettres de l’alphabet en majuscules
  • letters : les 26 lettres de l’alphabet en minuscules
  • month.name : les noms des 12 mois de l’année en anglais
  • month.abb : la version abrégée des 12 mois en anglais
  • pi : la constante mathématique p
LETTERS
 [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N"
[15] "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"
letters
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n"
[15] "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
length(letters)
[1] 26
month.name
 [1] "January"   "February"  "March"     "April"    
 [5] "May"       "June"      "July"      "August"   
 [9] "September" "October"   "November"  "December" 
month.abb
 [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep"
[10] "Oct" "Nov" "Dec"
length(month.abb)
[1] 12
pi
[1] 3.141593
length(pi)
[1] 1

Combiner des vecteurs

Pour combiner des vecteurs, rien de plus simple. Il suffit d’utiliser c ! Les valeurs des différents vecteurs seront mises bout à bout pour créer un unique vecteur.

x <- c(2, 1, 3, 4)
length(x)
[1] 4
y <- c(9, 1, 2, 6, 3, 0)
length(y)
[1] 6
z <- c(x, y)
z
 [1] 2 1 3 4 9 1 2 6 3 0
length(z)
[1] 10
min_maj <- c(letters, LETTERS)
min_maj
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n"
[15] "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z" "A" "B"
[29] "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P"
[43] "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"
length(min_maj)
[1] 52

Valeurs manquantes

Lorsqu’on travaille avec des données d’enquête, il est fréquent que certaines données soient manquantes, en raison d’un refus du participant de répondre à une question donnée ou d’un oubli ou d’un dysfonctionnement du matériel de mesure, etc.

Une valeur manquante s’indique sous R avec NA (pour not available). Cette valeur peut s’appliquer à n’importe quel type de vecteur, qu’il soit numérique, textuel ou logique.

taille <- c(1.88, NA, 1.65, 1.92, 1.76, NA)
sexe <- c("h", "f", NA, "h", NA, "f")

Les valeurs manquantes sont prises en compte dans le calcul de la longueur du vecteur.

length(taille)
[1] 6

Il ne faut pas confondre NA avec un autre objet qu’on rencontre sous R qui s’appelle NULL et qui représente l’objet vide. NULL ne contient absolument rien. La différence se comprend mieux lorsqu’on essaie de combiner ces objets :

c(NULL, NULL, NULL)
NULL
length(c(NULL, NULL, NULL))
[1] 0

On peut combiner NULL avec NULL, du vide plus du vide renverra toujours du vide dont la dimension est égale à zéro.

c(NA, NA, NA)
[1] NA NA NA
length(c(NA, NA, NA))
[1] 3

Par contre, un vecteur composé de trois valeurs manquantes a une longueur de 3, même si toutes ses valeurs sont manquantes.

Indexation par position

L’indexation est l’une des fonctionnalités les plus puissantes mais aussi les plus difficiles à maîtriser de R. Il s’agit d’opérations permettant de sélectionner des sous-ensembles de valeurs en fonction de différents critères. Il existe trois types d’indexation : (i) l’indexation par position, (ii) l’indexation par nom et (iii) l’indexation par condition. Le principe est toujours le même : on indique entre crochets ([]) ce qu’on souhaite garder ou non.

Pour rappel, les crochets s’obtiennent sur un clavier français de type PC en appuyant sur la touche Alt Gr et la touche ( ou ).

Commençons par l’indexation par position encore appelée indexation directe. Ce mode le plus simple d’indexation consiste à indiquer la position des éléments à conserver.

Reprenons notre vecteur taille :

taille
[1] 1.88   NA 1.65 1.92 1.76   NA

Si on souhaite le premier élément du vecteur, on peut faire :

taille[1]
[1] 1.88

Si on souhaite les trois premiers éléments ou les éléments 2, 5 et 6 :

taille[1:3]
[1] 1.88   NA 1.65
taille[c(2, 5, 6)]
[1]   NA 1.76   NA

Si on veut le dernier élément :

taille[length(taille)]
[1] NA

Il est tout à fait possible de sélectionner les valeurs dans le désordre :

taille[c(5, 1, 4, 3)]
[1] 1.76 1.88 1.92 1.65

Dans le cadre de l’indexation par position, il est également possible de spécifier des nombres négatifs, auquel cas cela signifiera toutes les valeurs sauf celles-là. Par exemple :

taille[c(-1, -5)]
[1]   NA 1.65 1.92   NA

À noter, si on indique une position au-delà de la longueur du vecteur, R renverra NA. Par exemple :

taille[23:25]
[1] NA NA NA

Des vecteurs nommés

Les différentes valeurs d’un vecteur peuvent être nommées. Une première manière de nommer les éléments d’un vecteur est de le faire à sa création :

sexe <- c(Michel = "h", Anne = "f", Dominique = NA, Jean = "h", Claude = NA, Marie = "f")

Lorsqu’on affiche le vecteur, la présentation change quelque peu.

sexe
   Michel      Anne Dominique      Jean    Claude     Marie 
      "h"       "f"        NA       "h"        NA       "f" 

La liste des noms s’obtient avec names.

names(sexe)
[1] "Michel"    "Anne"      "Dominique" "Jean"     
[5] "Claude"    "Marie"    

Pour ajouter ou modifier les noms d’un vecteur, on doit attribuer un nouveau vecteur de noms :

names(sexe) <- c("Michael", "Anna", "Dom", "John", "Alex", "Mary")
sexe
Michael    Anna     Dom    John    Alex    Mary 
    "h"     "f"      NA     "h"      NA     "f" 

Pour supprimer tous les noms, il y a la fonction unname :

anonyme <- unname(sexe)
anonyme
[1] "h" "f" NA  "h" NA  "f"

Indexation par nom

Lorsqu’un vecteur est nommé, il est dès lors possible d’accéder à ses valeurs à partir de leur nom. Il s’agit de l’indexation par nom.

sexe["Anna"]
Anna 
 "f" 
sexe[c("Mary", "Michael", "John")]
   Mary Michael    John 
    "f"     "h"     "h" 

Par contre il n’est pas possible d’utiliser l’opérateur - comme pour l’indexation directe. Pour exclure un élément en fonction de son nom, on doit utiliser une autre forme d’indexation, l’indexation par condition, expliquée dans la section suivante. On peut ainsi faire…

sexe[names(sexe) != "Dom"]

… pour sélectionner tous les éléments sauf celui qui s’appelle Dom.

Indexation par condition

L’indexation par condition consiste à fournir un vecteur logique indiquant si chaque élément doit être inclus (si TRUE) ou exclu (si FALSE). Par exemple :

sexe
Michael    Anna     Dom    John    Alex    Mary 
    "h"     "f"      NA     "h"      NA     "f" 
sexe[c(TRUE, FALSE, FALSE, TRUE, FALSE, FALSE)]
Michael    John 
    "h"     "h" 

Écrire manuellement une telle condition n’est pas très pratique à l’usage. Mais supposons que nous ayons également à notre disposition les deux vecteurs suivants, également de longueur 6.

urbain <- c(TRUE, FALSE, FALSE, FALSE, TRUE, TRUE)
poids <- c(80, 63, 75, 87, 82, 67)

Le vecteur urbain est un vecteur logique. On peut directement l’utiliser pour avoir le sexe des enquêtés habitant en milieu urbain :

sexe[urbain]
Michael    Alex    Mary 
    "h"      NA     "f" 

Supposons qu’on souhaite maintenant avoir la taille des individus pesant 80 kilogrammes ou plus. Nous pouvons effectuer une comparaison à l’aide des opérateurs de comparaison suivants :

Opérateur de comparaison Signification
== égal à
!= différent de
> strictement supérieur à
< strictement inférieur à
>= supérieur ou égal à
<= inférieur ou égal à

Voyons tout de suite un exemple :

poids >= 80
[1]  TRUE FALSE FALSE  TRUE  TRUE FALSE

Que s’est-il passé ? Nous avons fourni à R une condition et il nous a renvoyé un vecteur logique avec autant d’éléments qu’il y a d’observations et dont la valeur est TRUE si la condition est remplie et FALSE dans les autres cas. Nous pouvons alors utiliser ce vecteur logique pour obtenir la taille des participants pesant 80 kilogrammes ou plus :

taille[poids >= 80]
[1] 1.88 1.92 1.76

On peut combiner ou modifier des conditions à l’aide des opérateurs logiques habituels :

Opérateur logique Signification
& et logique
| ou logique
! négation logique

Comment les utilise-t-on ? Voyons tout de suite un exemple. Supposons que je veuille identifier les personnes pesant 80 kilogrammes ou plus et vivant en milieu urbain :

poids >= 80 & urbain
[1]  TRUE FALSE FALSE FALSE  TRUE FALSE

Les résultats sont différents si je souhaite isoler les personnes pesant 80 kilogrammes ou plus ou vivant milieu urbain :

poids >= 80 | urbain
[1]  TRUE FALSE FALSE  TRUE  TRUE  TRUE

Une remarque importante : quand l’un des termes d’une condition comporte une valeur manquante (NA), le résultat de cette condition n’est pas toujours TRUE ou FALSE, il peut aussi être à son tour une valeur manquante.

taille
[1] 1.88   NA 1.65 1.92 1.76   NA
taille > 1.8
[1]  TRUE    NA FALSE  TRUE FALSE    NA

On voit que le test NA > 1.8 ne renvoie ni vrai ni faux, mais NA.

Une autre conséquence importante de ce comportement est qu’on ne peut pas utiliser l’opérateur l’expression == NA pour tester la présence de valeurs manquantes. On utilisera à la place la fonction ad hoc is.na :

is.na(taille > 1.8)
[1] FALSE  TRUE FALSE FALSE FALSE  TRUE

Pour compliquer encore un peu le tout, lorsqu’on utilise une condition pour l’indexation, si la condition renvoie NA, R ne sélectionne pas l’élément mais retourne quand même la valeur NA. Ceci a donc des conséquences sur le résultat d’une indexation par comparaison.

Par exemple si je cherche à connaître le poids des personnes mesurant 1,80 mètre ou plus :

taille
[1] 1.88   NA 1.65 1.92 1.76   NA
poids
[1] 80 63 75 87 82 67
poids[taille > 1.8]
[1] 80 NA 87 NA

Les éléments pour lesquels la taille n’est pas connue ont été transformés en NA, ce qui n’influera pas le calcul d’une moyenne. Par contre, lorsqu’on utilisera assignation et indexation ensemble, cela peut créer des problèmes. Il est donc préférable lorsqu’on a des valeurs manquantes de les exclure ainsi :

poids[taille > 1.8 & !is.na(taille)]
[1] 80 87

Pour plus de détails sur les conditions et le calcul logique dans R, on pourra se référer au chapitre dédié.

Assignation par indexation

Dans tous les exemples précédents, on a utilisé l’indexation pour extraire une partie d’un vecteur, en plaçant l’opération d’indexation à droite de l’opérateur <-.

Mais l’indexation peut également être placée à gauche de cet opérateur d’assignation. Dans ce cas, les éléments sélectionnés par l’indexation sont alors remplacés par les valeurs indiquées à droite de l’opérateur <-.

Prenons donc un exemple simple :

v <- 1:5
v
[1] 1 2 3 4 5
v[1] <- 3
v
[1] 3 2 3 4 5

Cette fois, au lieu d’utiliser quelque chose comme x <- v[1], qui aurait placé la valeur du premier élément de v dans x, on a utilisé v[1] <- 3, ce qui a mis à jour le premier élément de v avec la valeur 3. Ceci fonctionne également pour les différents types d’indexation évoqués précédemment :

sexe["Alex"] <- "f"

Enfin on peut modifier plusieurs éléments d’un seul coup soit en fournissant un vecteur, soit en profitant du mécanisme de recyclage. Les deux commandes suivantes sont ainsi rigoureusement équivalentes :

sexe[c(1, 3, 4)] <- c("Homme", "Homme", "Homme")
sexe[c(1, 3, 4)] <- "Homme"

L’assignation par indexation peut aussi être utilisée pour ajouter une ou plusieurs valeurs à un vecteur :

length(sexe)
[1] 6
sexe[7] <- "f"
sexe
Michael    Anna     Dom    John    Alex    Mary         
"Homme"     "f" "Homme" "Homme"     "f"     "f"     "f" 
length(sexe)
[1] 7

On commence à voir comment l’utilisation de l’indexation par conditions et de l’assignation va nous permettre de faire des recodages (que nous aborderons plus en détail dans un chapitre dédié).

En résumé

  • Un vecteur est un objet unidimensionnel contenant une liste de valeurs qui sont toutes du même type (entières, numériques, textuelles ou logiques).
  • La fonction class permet de connaître le type du vecteur et la fonction length sa longueur, c’est-à-dire son nombre d’éléments.
  • La fonction c sert à créer et à combiner des vecteurs.
  • Les valeurs manquantes sont représentées avec NA.
  • Un vecteur peut être nommé, c’est-à-dire qu’un nom textuel a été associé à chaque élément. Cela peut se faire lors de sa création ou avec la fonction names.
  • L’indexation consiste à extraire certains éléments d’un vecteur. Pour cela, on indique ce qu’on souhaite extraire entre crochets ([]) juste après le nom du vecteur. Le type d’indexation dépend du type d’information transmise.
  • S’il s’agit de nombres entiers, c’est l’indexation par position : les nombres représentent la position dans le vecteur des éléments qu’on souhaite extraire. Un nombre négatif s’interprète comme tous les éléments sauf celui-là.
  • Si on indique des chaînes de caractères, c’est l’indexation par nom : on indique le nom des éléments qu’on souhaite extraire. Cette forme d’indexation ne fonctionne que si le vecteur est nommé.
  • Si on transmet des valeurs logiques, le plus souvent sous la forme d’une condition, c’est l’indexation par condition : TRUE indique les éléments à extraire et FALSE les éléments à exclure. Il faut être vigilant aux valeurs manquantes (NA) dans ce cas précis.
  • Enfin, il est possible de ne modifier que certains éléments d’un vecteur en ayant recours à la fois à l’indexation ([]) et à l’assignation (<-).

Listes et Tableaux de données

Il est préférable d’avoir déjà lu le chapitre Vecteurs, indexation et assignation avant d’aborder celui-ci.

Listes

Par nature, les vecteurs ne peuvent contenir que des valeurs de même type (numérique, textuel ou logique). Or, on peut avoir besoin de représenter des objets plus complexes composés d’éléments disparates. C’est ce que permettent les listes.

Propriétés et création

Une liste se crée tout simplement avec la fonction list :

l1 <- list(1:5, "abc")
l1
[[1]]
[1] 1 2 3 4 5

[[2]]
[1] "abc"

Une liste est un ensemble d’objets, quels qu’ils soient, chaque élément d’une liste pouvant avoir ses propres dimensions. Dans notre exemple précédent, nous avons créé une liste l1 composée de deux éléments : un vecteur d’entiers de longueur 5 et un vecteur textuel de longueur 1. La longueur d’une liste correspond aux nombres d’éléments qu’elle contient et s’obtient avec length :

length(l1)
[1] 2

Comme les vecteurs, une liste peut être nommée et les noms des éléments d’une liste sont accessibles avec names :

l2 <- list(minuscules = letters, majuscules = LETTERS, mois = month.name)
l2
$minuscules
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n"
[15] "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"

$majuscules
 [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N"
[15] "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"

$mois
 [1] "January"   "February"  "March"     "April"    
 [5] "May"       "June"      "July"      "August"   
 [9] "September" "October"   "November"  "December" 
length(l2)
[1] 3
names(l2)
[1] "minuscules" "majuscules" "mois"      

Que se passe-t-il maintenant si on effectue la commande suivante ?

l <- list(l1, l2)

À votre avis, quelle est la longueur de cette nouvelle liste l ? 5 ?

length(l)
[1] 2

Eh bien non ! Elle est de longueur 2 car nous avons créé une liste composée de deux éléments qui sont eux-mêmes des listes. Cela est plus lisible si on fait appel à la fonction str qui permet de visualiser la structure d’un objet.

str(l)
List of 2
 $ :List of 2
  ..$ : int [1:5] 1 2 3 4 5
  ..$ : chr "abc"
 $ :List of 3
  ..$ minuscules: chr [1:26] "a" "b" "c" "d" ...
  ..$ majuscules: chr [1:26] "A" "B" "C" "D" ...
  ..$ mois      : chr [1:12] "January" "February" "March" "April" ...

Une liste peut contenir tous types d’objets, y compris d’autres listes. Pour combiner les éléments d’une liste, il faut utiliser la fonction append :

l <- append(l1, l2)
length(l)
[1] 5
str(l)
List of 5
 $           : int [1:5] 1 2 3 4 5
 $           : chr "abc"
 $ minuscules: chr [1:26] "a" "b" "c" "d" ...
 $ majuscules: chr [1:26] "A" "B" "C" "D" ...
 $ mois      : chr [1:12] "January" "February" "March" "April" ...

On peut noter en passant qu’une liste peut tout à fait n’être que partiellement nommée.

Indexation

Les crochets simples ([]) fonctionnent comme pour les vecteurs. On peut utiliser à la fois l’indexation par position, l’indexation par nom et l’indexation par condition.

l
[[1]]
[1] 1 2 3 4 5

[[2]]
[1] "abc"

$minuscules
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n"
[15] "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"

$majuscules
 [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N"
[15] "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"

$mois
 [1] "January"   "February"  "March"     "April"    
 [5] "May"       "June"      "July"      "August"   
 [9] "September" "October"   "November"  "December" 
l[c(1, 3, 4)]
[[1]]
[1] 1 2 3 4 5

$minuscules
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n"
[15] "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"

$majuscules
 [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N"
[15] "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"
l[c("majuscules", "minuscules")]
$majuscules
 [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N"
[15] "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"

$minuscules
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n"
[15] "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
l[c(TRUE, TRUE, FALSE, FALSE, TRUE)]
[[1]]
[1] 1 2 3 4 5

[[2]]
[1] "abc"

$mois
 [1] "January"   "February"  "March"     "April"    
 [5] "May"       "June"      "July"      "August"   
 [9] "September" "October"   "November"  "December" 

Même si on extrait un seul élément, l’extraction obtenue avec les crochets simples renvoie toujours une liste, ici composée d’un seul élément :

str(l[1])
List of 1
 $ : int [1:5] 1 2 3 4 5

Supposons que je souhaite calculer la moyenne des valeurs du premier élément de ma liste. Essayons la commande suivante :

mean(l[1])
Warning in mean.default(l[1]): argument is not numeric or
logical: returning NA
[1] NA

Nous obtenons un message d’erreur. En effet, R ne sait pas calculer une moyenne à partir d’une liste. Ce qu’il lui faut, c’est un vecteur de valeurs numériques. Autrement dit, ce que nous cherchons à obtenir c’est le contenu même du premier élément de notre liste et non une liste à un seul élément.

C’est ici que les doubles crochets ([[]]) vont rentrer en jeu. Pour ces derniers, nous pourrons utiliser l’indexation par position ou l’indexation par nom, mais pas l’indexation par condition. De plus, le critère qu’on indiquera doit indiquer un et un seul élément de notre liste. Au lieu de renvoyer une liste à un élément, les doubles crochets vont renvoyer l’élément désigné. Vite, un exemple :

str(l[1])
List of 1
 $ : int [1:5] 1 2 3 4 5
str(l[[1]])
 int [1:5] 1 2 3 4 5

Maintenant, nous pouvons calculer notre moyenne :

mean(l[[1]])
[1] 3

Nous pouvons aussi tester l’indexation par nom.

l[["mois"]]
 [1] "January"   "February"  "March"     "April"    
 [5] "May"       "June"      "July"      "August"   
 [9] "September" "October"   "November"  "December" 

Mais il faut avouer que cette écriture avec doubles crochets et guillemets est un peu lourde. Heureusement, un nouvel acteur entre en scène : le symbole dollar ($). C’est un raccourci des doubles crochets pour l’indexation par nom qu’on utilise ainsi :

l$mois
 [1] "January"   "February"  "March"     "April"    
 [5] "May"       "June"      "July"      "August"   
 [9] "September" "October"   "November"  "December" 

Les écritures l$mois et l[["mois"]] sont équivalentes. Attention ! Cela ne fonctionne que pour l’indexation par nom.

l$1
Error: unexpected numeric constant in "l$1"

L’assignation par indexation fonctionne également avec les doubles crochets ou le signe dollar :

l[[2]] <- list(c("un", "vecteur", "textuel"))
l$mois <- c("Janvier", "Février", "Mars")
l
[[1]]
[1] 1 2 3 4 5

[[2]]
[[2]][[1]]
[1] "un"      "vecteur" "textuel"


$minuscules
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n"
[15] "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"

$majuscules
 [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N"
[15] "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"

$mois
[1] "Janvier" "Février" "Mars"   

Tableaux de données

Il y a un type d’objets que nous avons déjà abordé dans le chapitre Premier travail avec les données, il s’agit du tableau de données ou data frame en anglais.

Propriétés et création

Dans R, les tableaux de données sont tout simplement des listes avec quelques propriétés spécifiques :

  • les tableaux de données ne peuvent contenir que des vecteurs ;
  • tous les vecteurs d’un tableau de données ont la même longueur ;
  • tous les éléments d’un tableau de données sont nommés et ont chacun un nom unique.

Dès lors, un tableau de données correspond aux fichiers de données qu’on a l’habitude de manipuler dans d’autres logiciels de statistiques comme SPSS ou Stata. Les variables sont organisées en colonnes et les observations en lignes.

On peut créer un tableau de données avec la fonction data.frame :

df <- data.frame(
  sexe = c("f", "f", "h", "h"),
  age = c(52, 31, 29, 35),
  blond = c(FALSE, TRUE, TRUE, FALSE)
)
df
str(df)
'data.frame':   4 obs. of  3 variables:
 $ sexe : chr  "f" "f" "h" "h"
 $ age  : num  52 31 29 35
 $ blond: logi  FALSE TRUE TRUE FALSE

La fonction data.frame a un gros défaut : si on ne désactive pas l’option stringsAsFactors elle transforme les chaînes de caractères, ici la variable sexe en facteurs (un type de vecteur que nous aborderons plus en détail dans un prochain chapitre).

df <- data.frame(
  sexe = c("f", "f", "h", "h"),
  age = c(52, 31, 29, 35),
  blond = c(FALSE, TRUE, TRUE, FALSE),
  stringsAsFactors = FALSE
)
df
str(df)
'data.frame':   4 obs. of  3 variables:
 $ sexe : chr  "f" "f" "h" "h"
 $ age  : num  52 31 29 35
 $ blond: logi  FALSE TRUE TRUE FALSE

Un tableau de données étant une liste, la fonction length renverra le nombre d’éléments de la liste, donc dans le cas présent le nombre de variables, et names leurs noms :

length(df)
[1] 3
names(df)
[1] "sexe"  "age"   "blond"

Comme tous les éléments d’un tableau de données ont la même longueur, cet objet peut être vu comme bidimensionnel. Les fonctions nrow, ncol et dim donnent respectivement le nombre de lignes, le nombre de colonnes et les dimensions de notre tableau.

nrow(df)
[1] 4
ncol(df)
[1] 3
dim(df)
[1] 4 3

De plus, tout comme les colonnes ont un nom, il est aussi possible de nommer les lignes avec row.names :

row.names(df) <- c("Anna", "Mary-Ann", "Michael", "John")
df

Indexation

Les tableaux de données étant des listes, nous pouvons donc utiliser les crochets simples ([]), les crochets doubles ([[]]) et le symbole dollar ($) pour extraire des parties de notre tableau, de la même manière que pour n’importe quelle liste.

df[1]
df[[1]]
[1] "f" "f" "h" "h"
df$sexe
[1] "f" "f" "h" "h"

Cependant, un tableau de données étant un objet bidimensionnel, il est également possible d’extraire des données sur deux dimensions, à savoir un premier critère portant sur les lignes et un second portant sur les colonnes. Pour cela, nous utiliserons les crochets simples ([]) en séparant nos deux critères par une virgule (,).

Un premier exemple :

df
df[3, 2]
[1] 29

Cette première commande indique que nous souhaitons la troisième ligne de la seconde colonne, autrement dit l’âge de Michael. Le même résultat peut être obtenu avec l’indexation par nom, l’indexation par condition, ou un mélange de tout ça.

df["Michael", "age"]
[1] 29
df[c(F, F, T, F), c(c(F, T, F))]
[1] 29
df[3, "age"]
[1] 29
df["Michael", 2]
[1] 29

Il est également possible de préciser un seul critère. Par exemple, si je souhaite les deux premières observations, ou les variables sexe et blond :

df[1:2, ]
df[, c("sexe", "blond")]

Il a suffi de laisser un espace vide avant ou après la virgule. ATTENTION ! Il est cependant impératif de laisser la virgule pour indiquer à R qu’on souhaite effectuer une indexation à deux dimensions. Si on oublie la virgule, cela nous ramène au mode de fonctionnement des listes. Et le résultat n’est pas forcément le même :

df[2, ]
df[, 2]
[1] 52 31 29 35
df[2]

Au passage, on pourra noter quelques subtilités sur le résultat renvoyé.

str(df[2, ])
'data.frame':   1 obs. of  3 variables:
 $ sexe : chr "f"
 $ age  : num 31
 $ blond: logi TRUE
str(df[, 2])
 num [1:4] 52 31 29 35
str(df[2])
'data.frame':   4 obs. of  1 variable:
 $ age: num  52 31 29 35
str(df[[2]])
 num [1:4] 52 31 29 35

df[2, ] signifie qu’on veut toutes les variables pour le second individu. Le résultat est un tableau de données à une ligne et trois colonnes. df[2] correspond au mode d’extraction des listes et renvoie donc une liste à un élément, en l’occurrence un tableau de données à quatre observations et une variable. df[[2]] quant à lui renvoie le contenu de cette variable, soit un vecteur numérique de longueur quatre. Reste df[, 2] qui renvoie toutes les observations pour la seconde colonne. Or l’indexation bidimensionnelle a un fonctionnement un peu particulier : par défaut elle renvoie un tableau de données mais s’il y a une seule variable dans l’extraction, c’est un vecteur qui est renvoyé. Pour plus de détails, on pourra consulter l’entrée d’aide de [.data.frame.

Afficher les données

Prenons un tableau de données un peu plus conséquent, en l’occurrence un jeu de données disponible dans l’extension questionr et correspondant à un extrait de l’enquête Histoire de vie réalisée par l’INSEE en 2003. Il contient 2000 individus et 20 variables.

library(questionr)
data(hdv2003)
d <- hdv2003

Si on demande d’afficher l’objet d dans la console (résultat non reproduit ici), R va afficher l’ensemble du contenu de d à l’écran ce qui, sur un tableau de cette taille, ne sera pas très lisible. Pour une exploration visuelle, le plus simple est souvent d’utiliser la visionneuse intégrée à RStudio et qu’on peut appeler avec la fonction View.

View(d)

Les fonctions head et tail, qui marchent également sur les vecteurs, permettent d’afficher seulement les premières (respectivement les dernières) lignes d’un tableau de données :

head(d)
tail(d, 2)

L’extension dplyr, que nous n’aborderons en détails que plus tard, propose une fonction glimpse (ce qui signifie aperçu en anglais) qui permet de visualiser rapidement et de manière condensée le contenu d’un tableau de données.

library(dplyr)
glimpse(d)
Rows: 2,000
Columns: 20
$ id            <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11...
$ age           <int> 28, 23, 59, 34, 71, 35, 60, 47, 2...
$ sexe          <fct> Femme, Femme, Homme, Homme, Femme...
$ nivetud       <fct> "Enseignement superieur y compris...
$ poids         <dbl> 2634.3982, 9738.3958, 3994.1025, ...
$ occup         <fct> "Exerce une profession", "Etudian...
$ qualif        <fct> Employe, NA, Technicien, Technici...
$ freres.soeurs <int> 8, 2, 2, 1, 0, 5, 1, 5, 4, 2, 3, ...
$ clso          <fct> Oui, Oui, Non, Non, Oui, Non, Oui...
$ relig         <fct> Ni croyance ni appartenance, Ni c...
$ trav.imp      <fct> Peu important, NA, Aussi importan...
$ trav.satisf   <fct> Insatisfaction, NA, Equilibre, Sa...
$ hard.rock     <fct> Non, Non, Non, Non, Non, Non, Non...
$ lecture.bd    <fct> Non, Non, Non, Non, Non, Non, Non...
$ peche.chasse  <fct> Non, Non, Non, Non, Non, Non, Oui...
$ cuisine       <fct> Oui, Non, Non, Oui, Non, Non, Oui...
$ bricol        <fct> Non, Non, Non, Oui, Non, Non, Non...
$ cinema        <fct> Non, Oui, Non, Oui, Non, Oui, Non...
$ sport         <fct> Non, Oui, Oui, Oui, Non, Oui, Non...
$ heures.tv     <dbl> 0.0, 1.0, 0.0, 2.0, 3.0, 2.0, 2.9...

L’extension labelled propose une fonction look_for qui permet de lister les différentes variables d’un fichier de données :

library(labelled)
look_for(d)
pos   variable      label col_type values                                                         
<chr> <chr>         <chr> <chr>    <chr>                                                          
1     id            —     int      range: 1 - 2000                                                
2     age           —     int      range: 18 - 97                                                 
3     sexe          —     fct      Homme                                                          
                                   Femme                                                          
4     nivetud       —     fct      N'a jamais fait d'etudes                                       
                                   A arrete ses etudes, avant la derniere annee d'etudes primaires
                                   Derniere annee d'etudes primaires                              
                                   1er cycle                                                      
                                   2eme cycle                                                     
                                   Enseignement technique ou professionnel court                  
                                   Enseignement technique ou professionnel long                   
                                   Enseignement superieur y compris technique superieur           
5     poids         —     dbl      range: 78.0783403 - 31092.14132                                
6     occup         —     fct      Exerce une profession                                          
                                   Chomeur                                                        
                                   Etudiant, eleve                                                
                                   Retraite                                                       
                                   Retire des affaires                                            
                                   Au foyer                                                       
                                   Autre inactif                                                  
7     qualif        —     fct      Ouvrier specialise                                             
                                   Ouvrier qualifie                                               
                                   Technicien                                                     
                                   Profession intermediaire                                       
                                   Cadre                                                          
                                   Employe                                                        
                                   Autre                                                          
8     freres.soeurs —     int      range: 0 - 22                                                  
9     clso          —     fct      Oui                                                            
                                   Non                                                            
                                   Ne sait pas                                                    
10    relig         —     fct      Pratiquant regulier                                            
                                   Pratiquant occasionnel                                         
                                   Appartenance sans pratique                                     
                                   Ni croyance ni appartenance                                    
                                   Rejet                                                          
                                   NSP ou NVPR                                                    
11    trav.imp      —     fct      Le plus important                                              
                                   Aussi important que le reste                                   
                                   Moins important que le reste                                   
                                   Peu important                                                  
12    trav.satisf   —     fct      Satisfaction                                                   
                                   Insatisfaction                                                 
                                   Equilibre                                                      
13    hard.rock     —     fct      Non                                                            
                                   Oui                                                            
14    lecture.bd    —     fct      Non                                                            
                                   Oui                                                            
15    peche.chasse  —     fct      Non                                                            
                                   Oui                                                            
16    cuisine       —     fct      Non                                                            
                                   Oui                                                            
17    bricol        —     fct      Non                                                            
                                   Oui                                                            
18    cinema        —     fct      Non                                                            
                                   Oui                                                            
19    sport         —     fct      Non                                                            
                                   Oui                                                            
20    heures.tv     —     dbl      range: 0 - 12

Lorsqu’on a un gros tableau de données avec de nombreuses variables, il peut être difficile de retrouver la ou les variables d’intérêt. Il est possible d’indiquer à look_for un mot-clé pour limiter la recherche. Par exemple :

look_for(d, "trav")
pos   variable    label col_type values                      
<chr> <chr>       <chr> <chr>    <chr>                       
11    trav.imp    —     fct      Le plus important           
                                 Aussi important que le reste
                                 Moins important que le reste
                                 Peu important               
12    trav.satisf —     fct      Satisfaction                
                                 Insatisfaction              
                                 Equilibre  

Il est à noter que si la recherche n’est pas sensible à la casse (i.e. aux majuscules et aux minuscules), elle est sensible aux accents.

La méthode summary qui fonctionne sur tout type d’objet permet d’avoir quelques statistiques de base sur les différentes variables de notre tableau, les statistiques affichées dépendant du type de variable.

summary(d)
       id              age           sexe     
 Min.   :   1.0   Min.   :18.00   Homme: 899  
 1st Qu.: 500.8   1st Qu.:35.00   Femme:1101  
 Median :1000.5   Median :48.00               
 Mean   :1000.5   Mean   :48.16               
 3rd Qu.:1500.2   3rd Qu.:60.00               
 Max.   :2000.0   Max.   :97.00               
                                              
                                                 nivetud   
 Enseignement technique ou professionnel court       :463  
 Enseignement superieur y compris technique superieur:441  
 Derniere annee d'etudes primaires                   :341  
 1er cycle                                           :204  
 2eme cycle                                          :183  
 (Other)                                             :256  
 NA's                                                :112  
     poids                            occup     
 Min.   :   78.08   Exerce une profession:1049  
 1st Qu.: 2221.82   Chomeur              : 134  
 Median : 4631.19   Etudiant, eleve      :  94  
 Mean   : 5535.61   Retraite             : 392  
 3rd Qu.: 7626.53   Retire des affaires  :  77  
 Max.   :31092.14   Au foyer             : 171  
                    Autre inactif        :  83  
                      qualif    freres.soeurs   
 Employe                 :594   Min.   : 0.000  
 Ouvrier qualifie        :292   1st Qu.: 1.000  
 Cadre                   :260   Median : 2.000  
 Ouvrier specialise      :203   Mean   : 3.283  
 Profession intermediaire:160   3rd Qu.: 5.000  
 (Other)                 :144   Max.   :22.000  
 NA's                    :347                   
          clso                              relig    
 Oui        : 936   Pratiquant regulier        :266  
 Non        :1037   Pratiquant occasionnel     :442  
 Ne sait pas:  27   Appartenance sans pratique :760  
                    Ni croyance ni appartenance:399  
                    Rejet                      : 93  
                    NSP ou NVPR                : 40  
                                                     
                         trav.imp           trav.satisf 
 Le plus important           : 29   Satisfaction  :480  
 Aussi important que le reste:259   Insatisfaction:117  
 Moins important que le reste:708   Equilibre     :451  
 Peu important               : 52   NA's          :952  
 NA's                        :952                       
                                                        
                                                        
 hard.rock  lecture.bd peche.chasse cuisine    bricol    
 Non:1986   Non:1953   Non:1776     Non:1119   Non:1147  
 Oui:  14   Oui:  47   Oui: 224     Oui: 881   Oui: 853  
                                                         
                                                         
                                                         
                                                         
                                                         
 cinema     sport        heures.tv     
 Non:1174   Non:1277   Min.   : 0.000  
 Oui: 826   Oui: 723   1st Qu.: 1.000  
                       Median : 2.000  
                       Mean   : 2.247  
                       3rd Qu.: 3.000  
                       Max.   :12.000  
                       NA's   :5       

On peut également appliquer summary à une variable particulière.

summary(d$sexe)
Homme Femme 
  899  1101 
summary(d$age)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  18.00   35.00   48.00   48.16   60.00   97.00 

L’extension questionr fournit également une fonction bien pratique pour décrire les différentes variables d’un tableau de données. Il s’agit de describe. Faisons de suite un essai :

describe(d)
d 

 20  Variables      2000  Observations
------------------------------------------------------------
id 
       n  missing distinct     Info     Mean      Gmd 
    2000        0     2000        1     1000      667 
     .05      .10      .25      .50      .75      .90 
   101.0    200.9    500.8   1000.5   1500.2   1800.1 
     .95 
  1900.0 

lowest :    1    2    3    4    5, highest: 1996 1997 1998 1999 2000
------------------------------------------------------------
age 
       n  missing distinct     Info     Mean      Gmd 
    2000        0       78        1    48.16     19.4 
     .05      .10      .25      .50      .75      .90 
      22       26       35       48       60       72 
     .95 
      77 

lowest : 18 19 20 21 22, highest: 91 92 93 96 97
------------------------------------------------------------
sexe 
       n  missing distinct 
    2000        0        2 
                      
Value      Homme Femme
Frequency    899  1101
Proportion  0.45  0.55
------------------------------------------------------------
nivetud 
       n  missing distinct 
    1888      112        8 

lowest : N'a jamais fait d'etudes                                        A arrete ses etudes, avant la derniere annee d'etudes primaires Derniere annee d'etudes primaires                               1er cycle                                                       2eme cycle                                                     
highest: 1er cycle                                                       2eme cycle                                                      Enseignement technique ou professionnel court                   Enseignement technique ou professionnel long                    Enseignement superieur y compris technique superieur           
------------------------------------------------------------
poids 
       n  missing distinct     Info     Mean      Gmd 
    2000        0     1877        1     5536     4553 
     .05      .10      .25      .50      .75      .90 
   799.8   1161.7   2221.8   4631.2   7626.5  10819.0 
     .95 
 13647.9 

lowest :    78.07834    92.68033    92.93637   127.90122   153.01026
highest: 27195.83782 29548.78954 29570.78696 29657.94035 31092.14132
------------------------------------------------------------
occup 
       n  missing distinct 
    2000        0        7 

lowest : Exerce une profession Chomeur               Etudiant, eleve       Retraite              Retire des affaires  
highest: Etudiant, eleve       Retraite              Retire des affaires   Au foyer              Autre inactif        

Exerce une profession (1049, 0.524), Chomeur (134, 0.067),
Etudiant, eleve (94, 0.047), Retraite (392, 0.196), Retire
des affaires (77, 0.038), Au foyer (171, 0.086), Autre
inactif (83, 0.042)
------------------------------------------------------------
qualif 
       n  missing distinct 
    1653      347        7 

lowest : Ouvrier specialise       Ouvrier qualifie         Technicien               Profession intermediaire Cadre                   
highest: Technicien               Profession intermediaire Cadre                    Employe                  Autre                   

Ouvrier specialise (203, 0.123), Ouvrier qualifie (292,
0.177), Technicien (86, 0.052), Profession intermediaire
(160, 0.097), Cadre (260, 0.157), Employe (594, 0.359),
Autre (58, 0.035)
------------------------------------------------------------
freres.soeurs 
       n  missing distinct     Info     Mean      Gmd 
    2000        0       19    0.977    3.283     2.87 
     .05      .10      .25      .50      .75      .90 
       0        1        1        2        5        7 
     .95 
       9 

lowest :  0  1  2  3  4, highest: 14 15 16 18 22

0 (167, 0.084), 1 (407, 0.203), 2 (427, 0.214), 3 (284,
0.142), 4 (210, 0.105), 5 (151, 0.076), 6 (99, 0.050), 7
(94, 0.047), 8 (52, 0.026), 9 (37, 0.018), 10 (21, 0.011),
11 (21, 0.011), 12 (8, 0.004), 13 (10, 0.005), 14 (4,
0.002), 15 (4, 0.002), 16 (1, 0.000), 18 (2, 0.001), 22 (1,
0.000)
------------------------------------------------------------
clso 
       n  missing distinct 
    2000        0        3 
                                              
Value              Oui         Non Ne sait pas
Frequency          936        1037          27
Proportion       0.468       0.518       0.014
------------------------------------------------------------
relig 
       n  missing distinct 
    2000        0        6 

lowest : Pratiquant regulier         Pratiquant occasionnel      Appartenance sans pratique  Ni croyance ni appartenance Rejet                      
highest: Pratiquant occasionnel      Appartenance sans pratique  Ni croyance ni appartenance Rejet                       NSP ou NVPR                

Pratiquant regulier (266, 0.133), Pratiquant occasionnel
(442, 0.221), Appartenance sans pratique (760, 0.380), Ni
croyance ni appartenance (399, 0.200), Rejet (93, 0.046),
NSP ou NVPR (40, 0.020)
------------------------------------------------------------
trav.imp 
       n  missing distinct 
    1048      952        4 

Le plus important (29, 0.028), Aussi important que le reste
(259, 0.247), Moins important que le reste (708, 0.676),
Peu important (52, 0.050)
------------------------------------------------------------
trav.satisf 
       n  missing distinct 
    1048      952        3 
                                                       
Value        Satisfaction Insatisfaction      Equilibre
Frequency             480            117            451
Proportion          0.458          0.112          0.430
------------------------------------------------------------
hard.rock 
       n  missing distinct 
    2000        0        2 
                      
Value        Non   Oui
Frequency   1986    14
Proportion 0.993 0.007
------------------------------------------------------------
lecture.bd 
       n  missing distinct 
    2000        0        2 
                      
Value        Non   Oui
Frequency   1953    47
Proportion 0.977 0.024
------------------------------------------------------------
peche.chasse 
       n  missing distinct 
    2000        0        2 
                      
Value        Non   Oui
Frequency   1776   224
Proportion 0.888 0.112
------------------------------------------------------------
cuisine 
       n  missing distinct 
    2000        0        2 
                      
Value        Non   Oui
Frequency   1119   881
Proportion 0.559 0.440
------------------------------------------------------------
bricol 
       n  missing distinct 
    2000        0        2 
                      
Value        Non   Oui
Frequency   1147   853
Proportion 0.574 0.426
------------------------------------------------------------
cinema 
       n  missing distinct 
    2000        0        2 
                      
Value        Non   Oui
Frequency   1174   826
Proportion 0.587 0.413
------------------------------------------------------------
sport 
       n  missing distinct 
    2000        0        2 
                      
Value        Non   Oui
Frequency   1277   723
Proportion 0.638 0.362
------------------------------------------------------------
heures.tv 
       n  missing distinct     Info     Mean      Gmd 
    1995        5       29    0.972    2.247    1.877 
     .05      .10      .25      .50      .75      .90 
       0        0        1        2        3        4 
     .95 
       5 

lowest :  0.0  0.1  0.2  0.3  0.4, highest:  8.0  9.0 10.0 11.0 12.0
------------------------------------------------------------

Comme on le voit sur cet exemple, describe nous affiche le type des variables, les premières valeurs de chacune, le nombre de valeurs manquantes, le nombre de valeurs différentes (uniques) ainsi que quelques autres informations suivant le type de variables.

Il est possible de restreindre l’affichage à seulement quelques variables en indiquant le nom de ces dernières.

describe(d, c("age", "trav.satisf"))
age trav.satisf 

 20  Variables      2000  Observations
------------------------------------------------------------
id 
       n  missing distinct     Info     Mean      Gmd 
    2000        0     2000        1     1000      667 
     .05      .10      .25      .50      .75      .90 
   101.0    200.9    500.8   1000.5   1500.2   1800.1 
     .95 
  1900.0 

lowest :    1    2    3    4    5, highest: 1996 1997 1998 1999 2000
------------------------------------------------------------
age 
       n  missing distinct     Info     Mean      Gmd 
    2000        0       78        1    48.16     19.4 
     .05      .10      .25      .50      .75      .90 
      22       26       35       48       60       72 
     .95 
      77 

lowest : 18 19 20 21 22, highest: 91 92 93 96 97
------------------------------------------------------------
sexe 
       n  missing distinct 
    2000        0        2 
                      
Value      Homme Femme
Frequency    899  1101
Proportion  0.45  0.55
------------------------------------------------------------
nivetud 
       n  missing distinct 
    1888      112        8 

lowest : N'a jamais fait d'etudes                                        A arrete ses etudes, avant la derniere annee d'etudes primaires Derniere annee d'etudes primaires                               1er cycle                                                       2eme cycle                                                     
highest: 1er cycle                                                       2eme cycle                                                      Enseignement technique ou professionnel court                   Enseignement technique ou professionnel long                    Enseignement superieur y compris technique superieur           
------------------------------------------------------------
poids 
       n  missing distinct     Info     Mean      Gmd 
    2000        0     1877        1     5536     4553 
     .05      .10      .25      .50      .75      .90 
   799.8   1161.7   2221.8   4631.2   7626.5  10819.0 
     .95 
 13647.9 

lowest :    78.07834    92.68033    92.93637   127.90122   153.01026
highest: 27195.83782 29548.78954 29570.78696 29657.94035 31092.14132
------------------------------------------------------------
occup 
       n  missing distinct 
    2000        0        7 

lowest : Exerce une profession Chomeur               Etudiant, eleve       Retraite              Retire des affaires  
highest: Etudiant, eleve       Retraite              Retire des affaires   Au foyer              Autre inactif        

Exerce une profession (1049, 0.524), Chomeur (134, 0.067),
Etudiant, eleve (94, 0.047), Retraite (392, 0.196), Retire
des affaires (77, 0.038), Au foyer (171, 0.086), Autre
inactif (83, 0.042)
------------------------------------------------------------
qualif 
       n  missing distinct 
    1653      347        7 

lowest : Ouvrier specialise       Ouvrier qualifie         Technicien               Profession intermediaire Cadre                   
highest: Technicien               Profession intermediaire Cadre                    Employe                  Autre                   

Ouvrier specialise (203, 0.123), Ouvrier qualifie (292,
0.177), Technicien (86, 0.052), Profession intermediaire
(160, 0.097), Cadre (260, 0.157), Employe (594, 0.359),
Autre (58, 0.035)
------------------------------------------------------------
freres.soeurs 
       n  missing distinct     Info     Mean      Gmd 
    2000        0       19    0.977    3.283     2.87 
     .05      .10      .25      .50      .75      .90 
       0        1        1        2        5        7 
     .95 
       9 

lowest :  0  1  2  3  4, highest: 14 15 16 18 22

0 (167, 0.084), 1 (407, 0.203), 2 (427, 0.214), 3 (284,
0.142), 4 (210, 0.105), 5 (151, 0.076), 6 (99, 0.050), 7
(94, 0.047), 8 (52, 0.026), 9 (37, 0.018), 10 (21, 0.011),
11 (21, 0.011), 12 (8, 0.004), 13 (10, 0.005), 14 (4,
0.002), 15 (4, 0.002), 16 (1, 0.000), 18 (2, 0.001), 22 (1,
0.000)
------------------------------------------------------------
clso 
       n  missing distinct 
    2000        0        3 
                                              
Value              Oui         Non Ne sait pas
Frequency          936        1037          27
Proportion       0.468       0.518       0.014
------------------------------------------------------------
relig 
       n  missing distinct 
    2000        0        6 

lowest : Pratiquant regulier         Pratiquant occasionnel      Appartenance sans pratique  Ni croyance ni appartenance Rejet                      
highest: Pratiquant occasionnel      Appartenance sans pratique  Ni croyance ni appartenance Rejet                       NSP ou NVPR                

Pratiquant regulier (266, 0.133), Pratiquant occasionnel
(442, 0.221), Appartenance sans pratique (760, 0.380), Ni
croyance ni appartenance (399, 0.200), Rejet (93, 0.046),
NSP ou NVPR (40, 0.020)
------------------------------------------------------------
trav.imp 
       n  missing distinct 
    1048      952        4 

Le plus important (29, 0.028), Aussi important que le reste
(259, 0.247), Moins important que le reste (708, 0.676),
Peu important (52, 0.050)
------------------------------------------------------------
trav.satisf 
       n  missing distinct 
    1048      952        3 
                                                       
Value        Satisfaction Insatisfaction      Equilibre
Frequency             480            117            451
Proportion          0.458          0.112          0.430
------------------------------------------------------------
hard.rock 
       n  missing distinct 
    2000        0        2 
                      
Value        Non   Oui
Frequency   1986    14
Proportion 0.993 0.007
------------------------------------------------------------
lecture.bd 
       n  missing distinct 
    2000        0        2 
                      
Value        Non   Oui
Frequency   1953    47
Proportion 0.977 0.024
------------------------------------------------------------
peche.chasse 
       n  missing distinct 
    2000        0        2 
                      
Value        Non   Oui
Frequency   1776   224
Proportion 0.888 0.112
------------------------------------------------------------
cuisine 
       n  missing distinct 
    2000        0        2 
                      
Value        Non   Oui
Frequency   1119   881
Proportion 0.559 0.440
------------------------------------------------------------
bricol 
       n  missing distinct 
    2000        0        2 
                      
Value        Non   Oui
Frequency   1147   853
Proportion 0.574 0.426
------------------------------------------------------------
cinema 
       n  missing distinct 
    2000        0        2 
                      
Value        Non   Oui
Frequency   1174   826
Proportion 0.587 0.413
------------------------------------------------------------
sport 
       n  missing distinct 
    2000        0        2 
                      
Value        Non   Oui
Frequency   1277   723
Proportion 0.638 0.362
------------------------------------------------------------
heures.tv 
       n  missing distinct     Info     Mean      Gmd 
    1995        5       29    0.972    2.247    1.877 
     .05      .10      .25      .50      .75      .90 
       0        0        1        2        3        4 
     .95 
       5 

lowest :  0.0  0.1  0.2  0.3  0.4, highest:  8.0  9.0 10.0 11.0 12.0
------------------------------------------------------------

On peut également transmettre juste une variable :

describe(d$sexe)
d$sexe 
       n  missing distinct 
    2000        0        2 
                      
Value      Homme Femme
Frequency    899  1101
Proportion  0.45  0.55

En résumé

Les Listes

  • Les listes sont des objets unidimensionnels pouvant contenir tout type d’objet, y compris d’autres listes.
  • Elles ont une longueur qu’on obtient avec length.
  • On crée une liste avec list et on peut fusionner des listes avec append.
  • Tout comme les vecteurs, les listes peuvent être nommées et les noms des éléments s’obtiennent avec names.
  • Les crochets simples ([]) permettent de sélectionner les éléments d’une liste, en utilisant l’indexation par position, l’indexation par nom ou l’indexation par condition. Cela renvoie toujours une autre liste.
  • Les doubles crochets ([[]]) renvoient directement le contenu d’un élément de la liste qu’on aura sélectionné par position ou par nom.
  • Le symbole $ est un raccourci pour facilement sélectionner un élément par son nom, liste$nom étant équivalent à liste[["nom"]].

Les Tableaux de données

  • Les tableaux de données sont des listes avec des propriétés particulières :
    1. tous les éléments sont des vecteurs ;
    2. tous les vecteurs ont la même longueur ;
    3. tous les vecteurs ont un nom et ce nom est unique.
  • On peut créer un tableau de données avec data.frame.
  • Les tableaux de données correspondent aux fichiers de données qu’on utilise usuellement dans d’autres logiciels de statistiques : les variables sont représentées en colonnes et les observations en lignes.
  • Ce sont des objets bidimensionnels : ncol renvoie le nombre de colonnes et nrow le nombre de lignes.
  • Les doubles crochets ([[]]) et le symbole dollar ($) fonctionnent comme pour les listes et permettent d’accéder aux variables.
  • Il est possible d’utiliser des coordonnées bidimensionnelles avec les crochets simples ([]) en indiquant un critère sur les lignes puis un critère sur les colonnes, séparés par une virgule (,).

Facteurs et vecteurs labellisés

Dans le chapire sur les vecteurs, nous avons abordé les types fondementaux de vecteurs (numériques, textuels, logiques). Mais il existe de nombreux autres classes de vecteurs afin de représenter des données diverses (comme les dates). Dans ce chapitre, nous nous intéressons plus particulièrement aux variables catégorielles.

Les facteurs (ou factors an anglais) sont un type de vecteur géré nativement par R et utilisés dans de nombreux domaines (modèles statistiques, représentations graphiques, …).

Les facteurs sont souvent mis en regard des données labellisées telles qu’elles sont utilisées dans d’autres logiciels comme SPSS ou Stata. Or, les limites propres aux facteurs font qu’ils ne sont pas adpatés pour rendre compte des différents usages qui sont fait des données labellisées. Plusieurs extensions (telles que memisc ou Hmisc) ont proposé leur propre solution qui, bien qu’elles apportaient un plus pour la gestion des données labellisées, ne permettaient pas que celles-ci soient utilisées en dehors de ces extensions ou des extensions compatibles. Nous aborderons ici une nouvelle classe de vecteurs, la classe labelled, introduite par l’extension haven (que nous aborderons dans le cadre de l’import de données) et qui peut être manipulée avec l’extension homonyme labelled.

Facteurs

Dans ce qui suit on travaillera sur le jeu de données tiré de l’enquête Histoire de vie, fourni avec l’extension questionr.

library(questionr)
data(hdv2003)
d <- hdv2003

Jetons un œil à la liste des variables de d :

str(d)
'data.frame':   2000 obs. of  20 variables:
 $ id           : int  1 2 3 4 5 6 7 8 9 10 ...
 $ age          : int  28 23 59 34 71 35 60 47 20 28 ...
 $ sexe         : Factor w/ 2 levels "Homme","Femme": 2 2 1 1 2 2 2 1 2 1 ...
 $ nivetud      : Factor w/ 8 levels "N'a jamais fait d'etudes",..: 8 NA 3 8 3 6 3 6 NA 7 ...
 $ poids        : num  2634 9738 3994 5732 4329 ...
 $ occup        : Factor w/ 7 levels "Exerce une profession",..: 1 3 1 1 4 1 6 1 3 1 ...
 $ qualif       : Factor w/ 7 levels "Ouvrier specialise",..: 6 NA 3 3 6 6 2 2 NA 7 ...
 $ freres.soeurs: int  8 2 2 1 0 5 1 5 4 2 ...
 $ clso         : Factor w/ 3 levels "Oui","Non","Ne sait pas": 1 1 2 2 1 2 1 2 1 2 ...
 $ relig        : Factor w/ 6 levels "Pratiquant regulier",..: 4 4 4 3 1 4 3 4 3 2 ...
 $ trav.imp     : Factor w/ 4 levels "Le plus important",..: 4 NA 2 3 NA 1 NA 4 NA 3 ...
 $ trav.satisf  : Factor w/ 3 levels "Satisfaction",..: 2 NA 3 1 NA 3 NA 2 NA 1 ...
 $ hard.rock    : Factor w/ 2 levels "Non","Oui": 1 1 1 1 1 1 1 1 1 1 ...
 $ lecture.bd   : Factor w/ 2 levels "Non","Oui": 1 1 1 1 1 1 1 1 1 1 ...
 $ peche.chasse : Factor w/ 2 levels "Non","Oui": 1 1 1 1 1 1 2 2 1 1 ...
 $ cuisine      : Factor w/ 2 levels "Non","Oui": 2 1 1 2 1 1 2 2 1 1 ...
 $ bricol       : Factor w/ 2 levels "Non","Oui": 1 1 1 2 1 1 1 2 1 1 ...
 $ cinema       : Factor w/ 2 levels "Non","Oui": 1 2 1 2 1 2 1 1 2 2 ...
 $ sport        : Factor w/ 2 levels "Non","Oui": 1 2 2 2 1 2 1 1 1 2 ...
 $ heures.tv    : num  0 1 0 2 3 2 2.9 1 2 2 ...

Nous voyons que de nombreuses variables de ce tableau de données, telles que sexe ou nivetud, sont du type facteur.

Les facteurs prennent leurs valeurs dans un ensemble de modalités prédéfinies et ne peuvent en prendre d’autres. La liste des valeurs possibles est donnée par la fonction levels :

levels(d$sexe)
[1] "Homme" "Femme"

Si on veut modifier la valeur du sexe du premier individu de notre tableau de données avec une valeur non autorisée, on obient un message d’erreur et une valeur manquante est utilisée à la place :

d$sexe[1] <- "Chihuahua"
Warning in `[<-.factor`(`*tmp*`, 1, value = structure(c(NA,
2L, 1L, 1L, : invalid factor level, NA generated
d$sexe[1]
[1] <NA>
Levels: Homme Femme
d$sexe[1] <- "Homme"
d$sexe[1]
[1] Homme
Levels: Homme Femme

On peut très facilement créer un facteur à partir d’une variable textuelle avec la fonction factor :

v <- factor(c("H", "H", "F", "H"))
v
[1] H H F H
Levels: F H

Par défaut, les niveaux d’un facteur nouvellement créés sont l’ensemble des valeurs de la variable textuelle, ordonnées par ordre alphabétique. Cette ordre des niveaux est utilisé à chaque fois qu’on utilise des fonctions comme table, par exemple :

table(v)
v
F H 
1 3 

On peut modifier cet ordre au moment de la création du facteur en utilisant l’option levels :

v <- factor(c("H", "H", "F", "H"), levels = c("H", "F"))
table(v)
v
H F 
3 1 

On peut aussi modifier l’ordre des niveaux d’une variable déjà existante :

d$qualif <- factor(d$qualif, levels = c(
  "Ouvrier specialise", "Ouvrier qualifie",
  "Employe", "Technicien", "Profession intermediaire", "Cadre", "Autre"
))
table(d$qualif)

      Ouvrier specialise         Ouvrier qualifie 
                     203                      292 
                 Employe               Technicien 
                     594                       86 
Profession intermediaire                    Cadre 
                     160                      260 
                   Autre 
                      58 

L’extension questionr propose une interface interactive pour le réordonnancement des niveaux d’un facteur. Cette fonction, nommée iorder, vous permet de réordonner les modalités de manière graphique et de générer le code R correspondant.

Dans l’exemple précédant, si vous exécutez :

iorder(d, "qualif")

RStudio devrait ouvrir une fenêtre semblable à celle de la figure ci-dessous.

Interface de la commande iorder

Vous pouvez alors déplacer les modalités par glisser-déposer, vérifier le résultat dans l’onglet Vérification et, une fois le résultat satisfaisant, récupérer le code généré pour l’inclure dans votre script.

On peut également modifier les niveaux eux-mêmes. Imaginons que l’on souhaite créer une nouvelle variable qualif.abr contenant les noms abrégés des catégories socioprofessionnelles de qualif. On peut alors procéder comme suit :

d$qualif.abr <- factor(d$qualif,
  levels = c(
    "Ouvrier specialise", "Ouvrier qualifie",
    "Employe", "Technicien", "Profession intermediaire", "Cadre", "Autre"
  ),
  labels = c("OS", "OQ", "Empl", "Tech", "Interm", "Cadre", "Autre")
)
table(d$qualif.abr)

    OS     OQ   Empl   Tech Interm  Cadre  Autre 
   203    292    594     86    160    260     58 

Dans ce qui précède, le paramètre levels de factor permet de spécifier quels sont les niveaux retenus dans le facteur résultat, ainsi que leur ordre. Le paramètre labels, lui, permet de modifier les noms de ces niveaux dans le facteur résultat. Il est donc capital d’indiquer les noms de labels exactement dans le même ordre que les niveaux de levels. Pour s’assurer de ne pas avoir commis d’erreur, il est recommandé d’effectuer un tableau croisé entre l’ancien et le nouveau facteur :

table(d$qualif, d$qualif.abr)
                          
                            OS  OQ Empl Tech Interm Cadre
  Ouvrier specialise       203   0    0    0      0     0
  Ouvrier qualifie           0 292    0    0      0     0
  Employe                    0   0  594    0      0     0
  Technicien                 0   0    0   86      0     0
  Profession intermediaire   0   0    0    0    160     0
  Cadre                      0   0    0    0      0   260
  Autre                      0   0    0    0      0     0
                          
                           Autre
  Ouvrier specialise           0
  Ouvrier qualifie             0
  Employe                      0
  Technicien                   0
  Profession intermediaire     0
  Cadre                        0
  Autre                       58

On a donc ici un premier moyen d’effectuer un recodage des modalités d’une variable de type facteur. D’autres méthodes existent, que nous aborderons dans le chapitre Recodage.

À noter que par défaut, les valeurs manquantes ne sont pas considérées comme un niveau de facteur. On peut cependant les transformer en niveau en utilisant la fonction addNA. Ceci signifie cependant qu’elle ne seront plus considérées comme manquantes par R mais comme une modalité à part entière :

summary(d$trav.satisf)
  Satisfaction Insatisfaction      Equilibre           NA's 
           480            117            451            952 
summary(addNA(d$trav.satisf))
  Satisfaction Insatisfaction      Equilibre           <NA> 
           480            117            451            952 

La fonction addNAstr de l’extension questionr fait la même chose mais permet de spécifier l’étiquette de la modalité des valeurs manquantes.

library(questionr)
summary(addNAstr(d$trav.satisf, "Manquant"))
  Satisfaction Insatisfaction      Equilibre       Manquant 
           480            117            451            952 

Vecteurs labellisés

Nous abordons ici une nouvelle classe de vecteurs, la classe haven_labelled, introduite récemment par l’extension haven (que nous aborderons dans le cadre de l’import de données) et qui peut être manipulée avec l’extension homonyme labelled.

Pour cette section, nous allons utiliser d’autres données d’exemple, également disponibles dans l’extension questionr. Il s’agit d’un ensemble de trois tableaux de données (menages, femmes et enfants) contenant les données d’une enquête de fécondité. Commençons par les charger en mémoire :

library(questionr)
data(fecondite)

Pour ailleurs, nous allons avoir besoin de l’extension labelled qui permet de manipuler ces données labellisées.

library(labelled)

Les étiquettes de variable

Les étiquettes de variable permettent de donner un nom long, plus explicite, aux différentes colonnes d’un tableau de données (ou encore directement à un vecteur autonome).

La visonneuse de données de RStudio sait reconnaître et afficher ces étiquettes de variable lorsqu’elles existent. Essayez par exemple la commande suivante :

View(femmes)

Les fonctions look_for de l’extension laballed et describe de l’extension questionr affichent également les étiquettes de variables lorsqu’elles existent.

look_for(femmes, "rés")
pos   variable label               col_type values    
<chr> <chr>    <chr>               <chr>    <chr>     
7     milieu   Milieu de résidence dbl+lbl  [1] urbain
                                            [2] rural 
8     region   Région de résidence dbl+lbl  [1] Nord  
                                            [2] Est   
                                            [3] Sud   
                                            [4] Ouest
describe(femmes$id_femme)
[2000 obs.] Identifiant de l'enquêtée
numeric: 391 1643 85 881 1981 1072 1978 1607 738 1656 ...
min: 1 - max: 2000 - NAs: 0 (0%) - 2000 unique values

Pour manipuler les étiquettes de variable, il suffit d’utiliser la fonction var_label de l’extension labelled.

var_label(femmes$id_menage)
[1] "Identifiant du ménage"
var_label(femmes$id_menage) <- "ID du ménage auquel elle appartient"
var_label(femmes$id_menage)
[1] "ID du ménage auquel elle appartient"

On utilisera la valeur NULL pour supprimer une étiquette :

v <- c(1, 5, 2, 4, 1)
var_label(v)
NULL
var_label(v) <- "Ma variable"
var_label(v)
[1] "Ma variable"
var_label(v) <- NULL
var_label(v)
NULL
var_label(v) <- "Une autre étiquette"
var_label(v)
[1] "Une autre étiquette"

Le fait d’ajouter une étiquette à un vecteur ne modifie en rien son type. Regardons la structure de notre objet v :

str(v)
 num [1:5] 1 5 2 4 1
 - attr(*, "label")= chr "Une autre étiquette"

Que voit-on ? Notre vecteur possède maintenant ce qu’on appelle un attribut, c’est-à-dire une information supplémentaire qui lui est attachée. Un objet peut avoir plusieurs attributs. Ici, notre étiquette de variable est strocké dans un attribut nommé "label". Cela ne modifie en rien sa nature. Il ne s’agit que d’information en plus. Toutes les fonctions ne tiennent pas compte des étiquettes de variable. Peu importe ! La présence d’un attribut ne les empêchera de fonctionner. De même, même si l’extension labelled n’est pas installée sur votre machine, vous pourrez toujours manipuler vos données comme si de rien n’était.

On peut associer une étiquette de variable à n’importe quel type de variable, qu’elle soit numérique, textuelle, un facteur ou encore des dates.

Les étiquettes de valeur

Les étiquettes de valeur consistent à attribuer une étiquette textuelle à certaines valeurs d’un vecteur. Elles ne peuvent s’appliquer qu’aux vecteurs numériques ou textuels.

Lorsqu’un vecteur possède des étiquettes de valeur, sa classe change et devient labelled. Regardons déjà quelques exemples. Tout d’abord, jetons un apercu au contenu de l’objet femmes grace à la fonction glimpse de l’extension dplyr.

library(dplyr)
glimpse(femmes)
Rows: 2,000
Columns: 17
$ id_femme       <dbl> 391, 1643, 85, 881, 1981, 1072, ...
$ id_menage      <dbl> 381, 1515, 85, 844, 1797, 1015, ...
$ poids          <dbl> 1.803150, 1.803150, 1.803150, 1....
$ date_entretien <date> 2012-05-05, 2012-01-23, 2012-01...
$ date_naissance <date> 1997-03-07, 1982-01-06, 1979-01...
$ age            <dbl> 15, 30, 33, 43, 25, 18, 45, 23, ...
$ milieu         <dbl+lbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2...
$ region         <dbl+lbl> 4, 4, 4, 4, 4, 3, 3, 3, 3, 3...
$ educ           <dbl+lbl> 0, 0, 0, 0, 1, 0, 0, 0, 0, 0...
$ travail        <dbl+lbl> 1, 1, 0, 1, 1, 0, 1, 0, 1, 1...
$ matri          <dbl+lbl> 0, 2, 2, 2, 1, 0, 1, 1, 2, 5...
$ religion       <dbl+lbl> 1, 3, 2, 3, 2, 2, 3, 1, 3, 3...
$ journal        <dbl+lbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...
$ radio          <dbl+lbl> 0, 1, 1, 0, 0, 1, 1, 0, 0, 0...
$ tv             <dbl+lbl> 0, 0, 0, 0, 0, 1, 0, 0, 0, 0...
$ nb_enf_ideal   <dbl+lbl>  4,  4,  4,  4,  4,  5, 10, ...
$ test           <dbl+lbl> 0, 9, 0, 0, 1, 0, 0, 0, 0, 1...

Il apparaît que la variable region est de type haven_labelled. On peut le confirmer avec class.

class(femmes$region)
[1] "haven_labelled" "vctrs_vctr"     "double"        

Regardons les premières valeurs prises par cette variable.

head(femmes$region)
<labelled<double>[6]>: Région de résidence
[1] 4 4 4 4 4 3

Labels:
 value label
     1  Nord
     2   Est
     3   Sud
     4 Ouest

Nous voyons que quatre étiquettes de valeurs ont été associées à notre variable. Le code 1 correspond ainsi à la région Nord, le code 2 à la région Est, etc. Laissons de côté pour le moment la colonne is_na que nous aborderons dans une prochaine section.

La liste des étiquettes est également renvoyée par la fonction describe de questionr.

describe(femmes$region)
[2000 obs.] Région de résidence
labelled double: 4 4 4 4 4 3 3 3 3 3 ...
min: 1 - max: 4 - NAs: 0 (0%) - 4 unique values
4 value labels: [1] Nord [2] Est [3] Sud [4] Ouest

             n     %
[1] Nord   707  35.4
[2] Est    324  16.2
[3] Sud    407  20.3
[4] Ouest  562  28.1
Total     2000 100.0

L’extension labelled fournit la fonction val_labels qui renvoie la liste des étiquettes de valeurs d’une variable sous la forme d’un vecteur nommé et la fonction val_label (notez l’absence de ‘s’) qui renvoie l’étiquette associée à une valeur particulière. S’il n’y a pas d’étiquette de valeur, ces fonctions renvoient NULL.

val_labels(femmes$region)
 Nord   Est   Sud Ouest 
    1     2     3     4 
val_label(femmes$region, 2)
[1] "Est"
val_label(femmes$region, 6)
NULL
val_labels(femmes$age)
NULL

Re-regardons d’un peu plus près les premières valeurs de notre variable region.

head(femmes$region)
<labelled<double>[6]>: Région de résidence
[1] 4 4 4 4 4 3

Labels:
 value label
     1  Nord
     2   Est
     3   Sud
     4 Ouest

On s’aperçoit qu’il s’agit de valeurs numériques. Et l’affichage indique que notre variable est plus précisément du type labelled double. Pour rappel, double est synonyme de numeric. Autrement dit, la classe haven_labelled ne modifie pas le type sous-jacent d’un vecteur, que l’on peut toujours obtenir avec la fonction typeof. Nous pouvons également tester si notre variable est numérique avec la fonction is.numeric.

typeof(femmes$region)
[1] "double"
is.numeric(femmes$region)
[1] TRUE

À la différence des facteurs, le type original d’une variable labellisée n’est pas modifié par la présence d’étiquettes de valeur. Ainsi, il reste possible de calculer une moyenne à partir de notre variable region (même si cela n’est pas pertinent ici d’un point de vue sémantique).

mean(femmes$region)
[1] 2.412

Avec un facteur, nous aurions eu un bon message d’erreur.

mean(d$nivetud)
Warning in mean.default(d$nivetud): argument is not numeric
or logical: returning NA
[1] NA

Nous allons voir qu’il est aussi possible d’associer des étiquettes de valeurs à des vecteurs textuels. Créons tout d’abord un vecteur textuel qui nous servira d’exemple.

v <- c("f", "f", "h", "f", "h")
v
[1] "f" "f" "h" "f" "h"

Le plus facile pour lui associer des étiquettes de valeur est d’utiliser val_label.

val_label(v, "f") <- "femmes"
val_label(v, "h") <- "hommes"
v
<labelled<character>[5]>
[1] f f h f h

Labels:
 value  label
     f femmes
     h hommes
typeof(v)
[1] "character"

Notre vecteur v a automatiquement été transformé en un vecteur de la classe labelled. Mais son type sous-jacent est resté "character". Par ailleurs, les données elle-même n’ont pas été modifiées et ont conservé leurs valeurs originales.

Il est également possible de définir/modifier/supprimer l’ensemble des étiquettes de valeur d’une variable avec val_labels en lui assignant un vecteur nommé.

val_labels(v) <- c(Homme = "h", Femme = "f", "Valeur indéterminée" = "i")
v
<labelled<character>[5]>
[1] f f h f h

Labels:
 value               label
     h               Homme
     f               Femme
     i Valeur indéterminée

Comme précédemment, on utilisera NULL pour supprimer une ou toutes les étiquettes.

val_label(v, "i") <- NULL
v
<labelled<character>[5]>
[1] f f h f h

Labels:
 value label
     h Homme
     f Femme
val_labels(v) <- NULL
v
[1] "f" "f" "h" "f" "h"
class(v)
[1] "character"

Si l’on supprime toutes les étiquettes de valeur, alors notre vecteur retrouve sa classe initiale.

Assignation et condition

Les étiquettes de valeur sont plus souples que les facteurs, en ce sens qu’il n’est pas obligatoire d’indiquer une étiquette pour chaque valeur prise par une variable. Alors qu’il n’est pas possible avec un facteur d’assigner une valeur qui n’a pas été préalablement définie comme une des modalités possibles du facteur, nous n’avons pas cette limite avec les vecteurs labellisés.

femmes$region[3] <- 5

Important : quand on assigne une valeur à un facteur, on doit transmettre le texte correspondant à la modalité, alors que pour un vecteur labellisé on transmettra le code sous-jacent (pour rappel, les étiquettes de valeur ne sont qu’une information additionnelle).

De plus, nous avons vu que les données initiales n’étaient pas modifiées par l’ajout ou la suppression d’étiquettes de valeur, alors que pour les facteurs ce n’est pas vrai. Pour mieux comprendre, essayons la commande suivante :

unclass(factor(v))
[1] 1 1 2 1 2
attr(,"levels")
[1] "f" "h"

Un facteur stocke de manière interne les valeurs sous la forme d’une suite d’entiers, démarrant toujours par 1, forcément consécutifs, et dont les valeurs dépendent de l’ordre des facteurs. Pour s’en rendre compte :

unclass(factor(v, levels = c("h", "f")))
[1] 2 2 1 2 1
attr(,"levels")
[1] "h" "f"
unclass(factor(v, levels = c("f", "h")))
[1] 1 1 2 1 2
attr(,"levels")
[1] "f" "h"

Ce qui importe pour un facteur ce sont les modalités de ce dernier tandis que pour un vecteur labellisé ce sont les valeurs du vecteur elles-mêmes. Cela reste vrai pour l’écriture de conditions.

Prenons un premier exemple avec un facteur :

describe(d$sexe)
[2000 obs.] 
nominal factor: "Homme" "Femme" "Homme" "Homme" "Femme" "Femme" "Femme" "Homme" "Femme" "Homme" ...
2 levels: Homme | Femme
NAs: 0 (0%)

         n   %
Homme  900  45
Femme 1100  55
Total 2000 100
table(d$sexe == "Homme")

FALSE  TRUE 
 1100   900 
table(d$sexe == 1)

FALSE 
 2000 

La condition valide est celle utilisant "Homme" qui est la valeur de la modalité du facteur.

Et avec un vecteur labellisé ?

describe(femmes$milieu)
[2000 obs.] Milieu de résidence
labelled double: 2 2 2 2 2 2 2 2 2 2 ...
min: 1 - max: 2 - NAs: 0 (0%) - 2 unique values
2 value labels: [1] urbain [2] rural

              n     %
[1] urbain  912  45.6
[2] rural  1088  54.4
Total      2000 100.0
table(femmes$milieu == "urbain")
Erreur : Can't combine `..1` <character> and `..2` <double>.
table(femmes$milieu == 1)

FALSE  TRUE 
 1088   912 

Ici, pour être valide, la condition doit porter sur les valeurs de la variable elle-même et non sur les étiquette.

Quelques fonctions supplémentaires

L’extension labelled fournit quelques fonctions supplémentaires qui peuvent s’avérer utiles :

  • labelled pour créer directement des vecteurs labellisés ;
  • nolabel_to_na pour convertir les valeurs n’ayant pas d’étiquette en NA ;
  • val_labels_to_na qui, à l’inverse, converti les valeurs avec étiquette en NA ;
  • sort_val_labels pour trier l’ordre des étiquettes de valeurs.

On pourra se réferrer à l’aide de chacune de ces fonctions.

L’import de données labellisées et le recodage de variables (dont la conversion d’un vecteur labellisé en facteur) seront quant à eux abordés dans les prochains chapitres.

Organiser ses fichiers

Le répertoire de travail

À chaque fois que l’on demandera à R de charger ou d’enregistrer un fichier (en particulier lorsque l’on cherchera à importer des données, voir le chapitre dédié), R évaluera le nom du fichier qu’on lui a transmis par rapport au répertoire de travail actuellement défini, qui correspond au répertoire dans lequel R est actuellement en train de s’exécuter.

Pour connaître de le répertoire de travail actuel, on pourra utiliser la fonction getwd :

getwd()

Lorsque l’on travaille sous RStudio, le répertoire de travail est également affiché dans le quadrant inférieur droit, en gris, à la droite du mot Console (voir la capture d’écran ci-après).

Affichage du répertoire de travail sous RStudio
Affichage du répertoire de travail sous RStudio

Le symbole ~ correspond dans ce cas-là au répertoire utilisateur système, dont l’emplacement dépend du système d’exploitation. Sous Windows, il s’agit du répertoire Mes documents ou Documents (le nom varie suivant la version de Windows).

Le répertoire de travail peut être modifié avec la fonction setwd ou, sous RStudio, via le menu Session > Set Working Directory. Cependant, nous allons voir que nous n’aurons en pratique presque jamais besoin de le faire si l’on travaille avec RStudio.

Les projets dans RStudio

RStudio dispose d’une fonctionnalité très pratique pour organiser son travail en différents projets.

L’idée principale est de réunir tous les fichiers / documents relatifs à un même projet (que ce soit les données, les scripts, les rapports automatisés…) dans un répertoire dédié1.

Le menu Projects est accessible via une icône dédiée située tout en haut à droite (voir la capture d’écran ci-après).

Accès au menu Projects sous RStudio
Accès au menu Projects sous RStudio

Créer un nouveau projet

Dans le menu Projects on sélectionnera l’option New project. RStudio nous demandera dans un premier temps si l’on souhaite créer un projet (i) dans un nouveau répertoire, (ii) dans un répertoire déjà existant ou bien (iii) à partir d’un gestionnaire de versions (Git ou SVN).

Options de création de projet sous RStudio
Options de création de projet sous RStudio

Si vous débutez avec R, laissez de côté pour le moment les gestionnaires de versions qui sont destinés aux utilisateurs avancés. Dans le cadre d’un usage courant, on aura recours à New Directory.

RStudio nous demande alors le type de projet que l’on souhaite créer : (i) un projet vide, (ii) une extension R ou (iii) une application Shiny.

Les différents types de projet sous RStudio
Les différents types de projet sous RStudio

Il est encore un peu tôt pour se lancer dans la création de sa propre extension pour R (voir le chapitre Développer un package). Les applications Shiny (voir le chapitre dédié) sont des applications webs interactives. Là encore, on attendra une meilleure maîtrise de R pour se lancer dans ce type de projets. Dans un contexte d’analyse d’enquêtes, on choisira dès lors Empty project.

Création d’un projet dans un nouveau répertoire avec RStudio
Création d’un projet dans un nouveau répertoire avec RStudio

En premier lieu, on indiquera le nom de notre projet, qui sera également le nom du répertoire qui sera créé pour stocker les données du projet. Puis, on indiquera le répertoire parent, c’est-à-dire le répertoire dans lequel le répertoire de notre projet sera créé.

Les deux options suivantes concernent que les utilisateurs avancés. RStudio nous demande s’il on veut activer Git sur ce projet (Git étant un gestionnaire de versions, l’option n’étant affichée que si Git est installé sur votre PC) et s’il on souhaite utiliser l’extension packrat sur ce projet. packrat permet une gestion des extensions utilisées, projet par projet, ce qui n’est vraiment utile que dans le cadre d’analyses bien spécifiques.

Il ne nous reste plus qu’à cliquer sur Create Project.

Fonctionnement par défaut des projets

Lorsque l’on ouvre un projet, RStudio effectue différentes actions :

  • le nom du projet est affiché en haut à droite à côté de l’icône projets ;
  • une nouvelle session R est exécutée (ainsi s’il on passe d’un projet à un autre, les objets du projet qu’on vient de fermer ne sont plus en mémoire) ;
  • le répertoire de travail de R est défini comme étant le répertoire du projet (d’où le fait que l’on n’a pas à se préoccuper de définir le répertoire de travail lorsque l’on travaille avec des projets RStudio) ;
  • les objets créés (et sauvegardés dans le fichier .Rdata) lors d’une précédente séance de travail sont chargés en mémoire ;
  • l’historique des commandes saisies lors de nos précédentes séances de travail sont chargées dans l’onglet History ;
  • les scripts ouverts lors d’une précédente séance de travail sont automatiquement ouverts ;
  • divers paramètres de RStudio sont restaurés dans l’état dans lequel ils étaient la dernière fois que l’on a travaillé sur ce projet.

Autrement dit, lorsque l’on ouvre un projet RStudio, on revient à l’état de notre projet tel qu’il était la dernière fois que l’on a travaillé dessus. Pratique, non ?

Petite précision toutefois, les extensions que l’on avait chargées en mémoire avec la fonction library ne sont pas systématiquement rechargées en mémoire. Il faudra donc les appeler à nouveau lors de notre séance de travail.

Options des projets

Via le menu Projects > Projects options (accessible via l’icône projets en haut à droite), il est possible de personnaliser plusieurs options spécifiquement pour ce projet.

On retiendra surtout les 3 options principales de l’onglet General :

  • à l’ouverture du projet, doit-on charger en mémoire les objets sauvegardés lors d’une précédente séance de travail ?
  • à la fermeture du projet, doit-son sauvegarder (dans le fichier .Rdata) les différents objets en mémoire ? Si l’on choisit l’option Ask, alors une fenêtre vous demandera s’il faut faire cette sauvegarde chaque fois que vous fermerez le projet.
  • à la fermeture du projet, faut-il sauver l’historique des commandes ?

Naviguer d’un projet à un autre

RStudio se souvient des derniers projets sur lesquels vous avez travaillé. Lorsque vous cliquez sur le menu projets, vous verrez une liste de ces différents projets. Il suffit de cliquer sur le nom du projet désiré pour fermer automatiquement le projet en cours et ouvrir le projet désiré.

Votre projet n’apparait pas dans la liste ? Pas de panique. Il suffit de sélectionner Open project puis de parcourir vos répertoires pour indiquer à RStudio le projet à ouvrir.

Vous pouvez noter au passage une option Open project in new window qui permet d’ouvrir un projet dans une nouvelle fenêtre. En effet, il est tout à fait possible d’avoir plusieurs projets ouverts en même temps. Dans ce cas là, chaque projet aura sa propre session R. Les objets chargés en mémoire pour le projet A ne seront pas accessibles dans le cadre du projet B et inversement.

Voir aussi

On pourra se référer à la documentation officielle de RStudio : https://support.rstudio.com/hc/en-us/articles/200526207-Using-Projects.

Appeler un script depuis un autre script

Au sein d’un même projet, on peut avoir plusieurs scripts R. Cela permet de mieux organiser son code. Par exemple, on pourra avoir un premier script chargé d’importer les données, un second dédié à la création de nouvelles variables et un troisième dédié aux analyses statistiques.

Il est possible d’appeler un script au sein d’un autre script à l’aide de la fonction source à laquelle on précisera le nom de fichier du script en question.

Supposons par exemple que l’on ait préparé un script preparation.R chargé d’importer les données et de les mettre en forme. Au debut de notre script analyses.R, on pourra indiquer :

source("preparation.R")

Si l’on exécute notre script analyses.R, au moment de l’appel à source("preparation.R"), le fichier preparation.R sera chargé en mémoire et exécuté, puis le programme continuera avec les commandes suivant du fichier analyses.R.

Ici, on a indiqué à source le fichier preparation.R sans mention de répertoire. Dès lors, R va aller chercher ce fichier dans le répertoire de travail. Sur un gros projet, on peut être amené à organiser ses fichiers en plusieurs sous-répertoires pour une meilleure lisibilité. Dès lors, il faudra indiquer le chemin relatif pour accéder à un fichier, c’est-à-dire le chemin à partir du répertoire de travail. Supposons que notre fichier preparation.R est enregistré dans un sous-répertoire import. Dans ce cas-là, on appelera notre fichier ainsi :

source("import/preparation.R")

On remarquera qu’on a utilisé une barre oblique ou slash (/) entre le nom du répertoire et le nom du fichier, ce qui est l’usage courant sous Linux et Mac OS X, tandis que sous Windows on utilise d’ordinaire une barre oblique inversée ou antislash (\). Sous R, on utilisera toujours la barre oblique simple (/), R sachant « retrouver ses petits » selon le système d’exploitation.

Par ailleurs, l’autocomplétion de RStudio fonctionne aussi pour les noms de fichiers. Essayez par exemple d’appuyer sur la touche Tab après avoir taper les premières lettres du nom de votre fichier.


  1. Dans lequel il sera possible de créer des sous-répertoires.

Import de données

Importer des données est souvent l’une des première opérations que l’on effectue lorsque l’on débute sous R, et ce n’est pas la moins compliquée. En cas de problème il ne faut donc pas hésiter à demander de l’aide par les différents moyens disponibles (voir le chapitre Où trouver de l’aide ?) avant de se décourager.

N’hésitez donc pas à relire régulièrement ce chapitre en fonction de vos besoins.

Avant toute chose, il est impératif de bien organiser ses différents fichiers (voir le chapitre dédié). Concernant les données sources que l’on utilisera pour ses analyses, je vous recommande de les placer dans un sous-répertoire dédié de votre projet.

Lorsque l’on importe des données, il est également impératif de vérifier que l’import s’est correctement déroulé (voir la section Inspecter les données du chapitre Premier travail avec les données).

Importer des fichiers texte

Les fichiers texte constituent un des formats les plus largement supportés par la majorité des logiciels statistiques. Presque tous permettent d’exporter des données dans un format texte, y compris les tableurs comme Libre Office, Open Office ou Excel.

Cependant, il existe une grande variétés de format texte, qui peuvent prendre différents noms selon les outils, tels que texte tabulé ou texte (séparateur : tabulation), CSV (pour comma-separated value, sachant que suivant les logiciels le séparateur peut être une virgule ou un point-virgule).

Structure d’un fichier texte

Dès lors, avant d’importer un fichier texte dans R, il est indispensable de regarder comment ce dernier est structuré. Il importe de prendre note des éléments suivants :

  • La première ligne contient-elle le nom des variables ? Ici c’est le cas.
  • Quel est le caractère séparateur entre les différentes variables (encore appelé séparateur de champs) ? Dans le cadre d’un fichier CSV, il aurait pu s’agir d’une virgule ou d’un point-virgule.
  • Quel est le caractère utilisé pour indiquer les décimales (le séparateur décimal) ? Il s’agit en général d’un point (à l’anglo-saxonne) ou d’une virgule (à la française).
  • Les valeurs textuelles sont-elles encadrées par des guillemets et, si oui, s’agit-il de guillements simple (') ou de guillemets doubles (") ?
  • Pour les variables textuelles, y a-t-il des valeurs manquantes et si oui comment sont-elles indiquées ? Par exemple, le texte NA est parfois utilisé.

Il ne faut pas hésitez à ouvrir le fichier avec un éditeur de texte pour le regarder de plus près.

Interface graphique avec RStudio

RStudio fournit une interface graphique pour faciliter l’import d’un fichier texte. Pour cela, il suffit d’aller dans le menu File > Import Dataset et de choisir l’option From CSV1. Cette option est également disponible via l’onglet Environment dans le quadrant haut-droite.

Pour la suite de la démonstration, nous allons utiliser le fichier exemple http://larmarange.github.io/analyse-R/data/exemple_texte_tabule.txt.

Importer un fichier texte avec RStudio
Importer un fichier texte avec RStudio

L’interface de RStudio vous présente sous Import Options les différentes options d’import disponible. La section Data Preview vous permet de voir en temps réel comment les données sont importées. La section Code Preview vous indique le code R correspondant à vos choix. Il n’y a plus qu’à le copier/coller dans un de vos scripts ou à cliquer sur Import pour l’exécuter.

Vous pourrez remarquer que RStudio fait appel à l’extension readr du tidyverse pour l’import des données via la fonction read_csv.

readr essaie de deviner le type de chacune des colonnes, en se basant sur les premières observations. En cliquant sur le nom d’une colonne, il est possible de modifier le type de la variable importée. Il est également possible d’exclure une colonne de l’import (skip).

Dans un script

L’interface graphique de RStudio fournit le code d’import. On peut également l’adapter à ces besoins en consultant la page d’aide de read_csv pour plus de détails. Par exemple :

library(readr)
d <- read_delim("http://larmarange.github.io/analyse-R/data/exemple_texte_tabule.txt",
  delim = "\t", quote = "'"
)

-- Column specification ------------------------------------
cols(
  Sexe = col_character(),
  Age = col_double(),
  Taille = col_number(),
  Etudes = col_character()
)

Le premier élément peut être un lien internet ou bien le chemin local vers un fichier. Afin d’organiser au mieux vos fichiers, voir le chapitre Organiser ses fichiers.

Certains caractères sont parfois précédés d’une barre oblique inversée ou antislash (\). Cela correspond à des caractères spéciaux. En effet, " est utilisé pour délimiter dans le code le début et la fin d’une chaîne de caractères. Comment indiquer à R le caractère " proprement dit. Et bien avec \". De même, \t sera interprété comme une tabulation et non comme la lettre t.

Pour une liste complète des caractères spéciaux, voir ?Quotes.

class(d)
[1] "spec_tbl_df" "tbl_df"      "tbl"         "data.frame" 
d

L’objet renvoyé est un tableau de données ou data.frame. Plus précisément, il s’agit d’un tibble, c’est-à-dire un tableau de données légèrement amélioré facilement utilisable avec les différentes extensions du tidyverse. Pas de panique, c’est un tableau de données comme les autres. Disons qu’il est possible de faire un peu plus de choses avec. Pour cela, voir le chapitre dédié à dplyr.

readr propose plusieurs fonctions proches : read_delim, read_csv, read_csv2 et read_tsv. Elles fonctionnent toutes de manière identique et ont les mêmes arguments. Seule différence, les valeurs par défaut de certainsparamètres.

Dans des manuels ou des exemples en ligne, vous trouverez parfois mention des fonctions read.table, read.csv, read.csv2, read.delim ou encore read.delim2. Il s’agit des fonctions natives et historiques de R (extension utils) dédiées à l’import de fichiers textes. Elles sont similaires à celles de readr dans l’idée générale mais diffèrent dans leurs détails et les traitements effectués sur les données (pas de détection des dates par exemple). Pour plus d’information, vous pouvez vous référer à la page d’aide de ces fonctions.

Importer depuis des logiciels de statistique

Plusieurs extensions existent pour importer des fichiers de données issus d’autres logiciels de statistiques. En premier lieu, il y a foreign, installée par défaut avec R et décrite en détails dans le manuel R Data Import/Export disponible sur http://cran.r-project.org/manuals.html. Un des soucis majeurs de cette extension réside dans la manière dont elle traite les métadonnées utilisées en particulier dans les fichiers SAS, SPSS et Stata, à savoir les étiquettes de variable, les étiquettes de valeur et les valeurs manquantes déclarées. En effet, chaque fonction va importer ces métadonnées sous la forme d’attributs dont le nom diffère d’une fonction à l’autre. Par ailleurs, selon les options retenues, les variables labellisées seront parfois transformées ou non en facteurs. Enfin, foreign ne sait pas toujours importer les différents types de variables représentant des dates et des heures.

L’extension haven (qui fait partie du tidyverse) tente de remédier à plusieurs des limitations rencontrées avec foreign :

  • le format des métadonnées importé est uniforme, quel que soit le type de fichier source (SAS, SPSS ou Stata) ;
  • les variables labellisées ne sont pas transformées en facteurs, mais héritent d’une nouvelle classe haven_labelled, la valeur initiale restant inchangée ;
  • les différents formats de date sont convertis dans des classes R appropriées, utilisables en particulier avec lubridate ;
  • haven peut lire les fichiers SAS natifs (extension .sas7bdat) ce que ne peut pas faire foreign ;
  • haven peut lire les fichiers Stata 13 et 14, alors que foreign ne sait lire ces fichiers que jusqu’à la version 12 ;
  • les tableaux de données produits ont directement la classe tbl_df ce qui permets d’utiliser directement les fonctionnalités de l’extension dplyr.

À noter, il est également possible d’utiliser l’interface graphique de RStudio pour l’import des fichiers SPSS, Stata, SAS et Excel.

Données labellisées

À la différence de foreign, haven ne convertit pas les variables avec des étiquettes de valeurs en facteurs mais en vecteurs labellisés du type haven_labelled qui sont présentés en détail dans le chapitre Facteurs et vecteurs labellisés et dans le chapitre recodage de variables où est discutée la question de savoir à quel moment convertir les données labellisées.

SPSS

Les fichiers générés par SPSS sont de deux types : les fichiers SPSS natifs natifs (extension .sav) et les fichiers au format SPSS export (extension .por).

Dans les deux cas, on aura recours à la fonction read_spss :

library(haven)
donnees <- read_spss("data/fichier.sav", user_na = TRUE)

Gestion des valeurs manquantes

Dans SPSS, il est possible de définir des valeurs à considérées comme manquantes. Plus précisément jusqu’à 3 valeurs spécfiques et/ou les valeurs comprises entre un minimum et un maximum. Par défaut, read_spss convertir toutes ces valeurs en NA lors de l’import.

Or, il est parfois important de garder les différentes valeurs originelles, notamment dans le cadre de l’analyse de données d’enquête, un manquant du type ne sait pas n’étant pas équivalent à un manquant du type refus ou du type variable non collectée.

Dès lors, nous vous recommandons d’appeler read_spss avec l’option user_na = TRUE. Dans ce cas-là, les valeurs manquantes définies dans SPSS ne seront pas converties en NA, tout en conservant la définition des valeurs définies comme manquantes. Il sera alors toujours possible de convertir, dans un second temps et en fonction des besoins, ces valeurs à considérer comme manquantes en NA grace aux fonctions de l’extension labelled, en particulier user_na_to_na, na_values et na_range.

À noter que les fonctions describe et freq de l’extension questionr que nous arboderons dans d’autres chapitres savent exploiter ces valeurs à considérer comme manquantes.

Si vous préférez utiliser l’extension foreign, la fonction correspondante est read.spss. On indiquera à la fonction de renvoyer un tableau de données avec l’argument to.data.frame = TRUE.

Par défaut, les variables numériques pour lesquelles des étiquettes de valeurs ont été définies sont transformées en variables de type facteur, les étiquettes définies dans SPSS étant utilisées comme labels du facteur. De même, si des valeurs manquantes ont été définies dans SPSS, ces dernières seront toutes transformées en NA (R ne permettant pas de gérer plusieurs types de valeurs manquantes). Ce comportement peut être modifié avec use.value.labels et use.missings.

library(foreign)
donnees <- read.spss("data/fichier.sav", to.data.frame = TRUE, use.value.labels = FALSE, use.missings = FALSE)

Il est important de noter que read.spss de l’extension foreign ne sait pas importer les dates. Ces dernières sont donc automatiquement transformées en valeurs numériques.

SPSS stocke les dates sous la forme du nombre de secondes depuis le début du calendrier grégorien, à savoir le 14 octobre 1582. Dès lors, si l’on des dates dans un fichier SPSS et que ces dernières ont été converties en valeurs numériques, on pourra essayer la commande suivante :

donnees$date <- as.POSIXlt(donnees$date, origin = "1582-10-14")

SAS

Les fichiers SAS se présentent en général sous deux format : format SAS export (extension .xport ou .xpt) ou format SAS natif (extension .sas7bdat).

Les fichiers SAS natifs peuvent être importées directement avec read_sas de l’extension haven :

library(haven)
donnees <- read_sas("data/fichier.sas7bdat")

Au besoin, on pourra préciser en deuxième argument le nom d’un fichier SAS catalogue (extension .sas7bcat) contenant les métadonnées du fichier de données.

library(haven)
donnees <- read_sas("data/fichier.sas7bdat", "data/fichier.sas7bcat")

Les fichiers au format SAS export peuvent être importés via la fonction read.xport de l’extension foreign. Celle-ci s’utilise très simplement, en lui passant le nom du fichier en argument :

library(foreign)
donnees <- read.xport("data/fichier.xpt")

Stata

Pour les fichiers Stata (extension .dta), on aura recours aux fonctions read_dta et read_stata de l’extension haven. Ces deux fonctions sont identiques.

library(haven)
donnees <- read_dta("data/fichier.dta")

Gestion des valeurs manquantes

Dans Stata, il est possible de définir plusieurs types de valeurs manquantes, qui sont notées sous la forme .a à .z. Pour conserver cette information lors de l’import, haven a introduit dans R le concept de tagged NA ou tagged missing value. Plus de détails sur ces données manquantes étiquettées, on se référera à la page d’aide de la fonction tagged_na.

Si l’on préfère utiliser l’extension foreign, on aura recours à la fonction read.dta.

L’option convert.factors indique si les variables labellisées doit être converties automatiquement en facteurs. Pour un résultat similaire à celui de haven, on choisira donc :

library(foreign)
donnees <- read.dta("data/fichier.dta", convert.factors = FALSE)

L’option convert.dates permet de convertir les dates du format Stata dans un format de dates géré par R. Cependant, cela ne marche pas toujours. Dans ces cas là, l’opération suivante peut fonctionner. Sans garantie néanmoins, il est toujours vivement conseillé de vérifier le résultat obtenu !

donnees$date <- as.Date(donnees$Date, origin = "1960-01-01")

Excel

Une première approche pour importer des données Excel dans R consiste à les exporter depuis Excel dans un fichier texte (texte tabulé ou CSV) puis de suivre la procédure d’importation d’un fichier texte.

Une feuille Excel peut également être importée directement avec l’extension readxl qui appartient à la même famille que haven et readr.

La fonction read_excel permet d’importer à la fois des fichiers .xls (Excel 2003 et précédents) et .xlsx (Excel 2007 et suivants).

library(readxl)
donnees <- read_excel("data/fichier.xlsx")

Une seule feuille de calculs peut être importée à la fois. On pourra préciser la feuille désirée avec sheet en indiquant soit le nom de la feuille, soit sa position (première, seconde, …).

donnees <- read_excel("data/fichier.xlsx", sheet = 3)
donnees <- read_excel("data/fichier.xlsx", sheet = "mes_donnees")

On pourra préciser avec col_names si la première ligne contient le nom des variables.

Par défaut, read_excel va essayer de deviner le type (numérique, textuelle, date) de chaque colonne. Au besoin, on pourra indiquer le type souhaité de chaque colonne avec col_types.

RStudio propose également pour les fichiers Excel un assitant d’importation, similaire à celui pour les fichiers texte, permettant de faciliter l’import.

Une première alternative est l’extenstion openxlsx et sa fonction read.xlsx.

Une seconde alternative est l’extension xlsx qui propose deux fonctions différentes pour importer des fichiers Excel : read.xlsx et read.xlsx2. La finalité est la même mais leur fonctionnement interne est différent. En cas de difficultés d’import, on pourra tester l’autre. Il est impératif de spécifier la position de la feuille de calculs que l’on souhaite importer.

library(xlsx)
donnees <- read.xlsx("data/fichier.xlsx", 1)

dBase

L’Insee et d’autres producteur de données diffusent leurs fichiers au format dBase (extension .dbf). Ceux-ci sont directement lisibles dans R avec la fonction read.dbf de l’extension foreign.

library(foreign)
donnees <- read.dbf("data/fichier.dbf")

La principale limitation des fichiers dBase est de ne pas gérer plus de 256 colonnes. Les tables des enquêtes de l’Insee sont donc parfois découpées en plusieurs fichiers .dbf qu’il convient de fusionner avec la fonction merge. L’utilisation de cette fonction est détaillée dans le chapitre sur la fusion de tables.

Feuille de calcul Google Sheets

Pour importer des données stockées sous formes de feuilles de calcul Google, on pourra se référer à l’extension googlesheets.

Données spatiales

Shapefile

Les fichiers Shapefile sont couramment utilisés pour échanger des données géoréférencées. La majorité des logiciels de SIG (systèmes d’informations géographiques) sont en capacité d’importer et d’exporter des données dans ce format.

Un shapefile contient toute l’information liée à la géométrie des objets décrits, qui peuvent être :

  • des points
  • des lignes
  • des polygones

Son extension est classiquement .shp et il est toujours accompagné de deux autres fichiers de même nom et d’extensions :

  • un fichier .dbf, qui contient les données attributaires relatives aux objets contenus dans le shapefile
  • un fichier .shx, qui stocke l’index de la géométrie

D’autres fichiers peuvent être également fournis :

  • .sbn et .sbx - index spatial des formes.
  • .fbn et .fbx - index spatial des formes pour les shapefile en lecture seule
  • .ain et .aih - index des attributs des champs actifs dans une table ou dans une table d’attributs du thème
  • .prj - information sur le système de coordonnées
  • .shp.xml - métadonnées du shapefile.
  • .atx - fichier d’index des attributs pour le fichier .dbf
  • .qix

En premier lieu, il importe que tous les fichiers qui compose un même shapefile soit situés dans le même répertoire et aient le même nom (seule l’extension étant différente).

L’extension maptools fournit les fonctions permettant d’importer un shapefile dans R. Le résultat obtenu utilisera l’une des différentes classes spatiales fournies par l’extension sp.

La fonction générique d’import est readShapeSpatial :

library(maptools)
donnees_spatiales <- readShapeSpatial("data/fichier.shp")

Si l’on connait déjà le type de données du shapefile (points, lignes ou polygones), on pourra utiliser directement readShapePoints, readShapeLines ou readShapePoly.

Rasters

Il existe de multiples formats pour stocker des données matricielles spatiales. L’un des plus communs est le format ASCII grid aussi connu sous le nom de Arc/Info ASCII grid ou ESRI grid. L’extension de ce format n’est pas toujours uniforme. On trouve parfois .asc ou encore .ag voir même .txt.

Pour importer ce type de fichier, on pourra avoir recours à la fonction readAsciiGrid de l’extension maptools. Le résultat sera, par défaut, au format SpatialGridDataFrame de l’extension sp.

library(maptools)
donnees_spatiales <- readAsciiGrid("data/fichier.asc")

L’extension raster permet d’effectuer de multiples manipulations sur les données du type raster. Elle est en capacité d’importer des données depuis différents formats (plus précisément les formats pris en charge par la librairie GDAL, http://www.gdal.org/).

De plus, les fichiers raster pouvant être particulièrement volumineux (jusqu’à plusieurs Go de données), l’extension raster est capable de travailler sur un fichier raster sans avoir à le charger intégralement en mémoire.

Pour plus d’informations, voir les fonctions raster et getValues.

Connexion à des bases de données

Interfaçage via l’extension DBI

R est capable de s’interfacer avec différents systèmes de bases de données relationnelles, dont SQLite, MS SQL Server, PostgreSQL, MariaDB, etc.

Pour illustrer rapidement l’utilisation de bases de données, on va créer une base SQLite d’exemple à l’aide du code R suivant, qui copie la table du jeu de données mtcars dans une base de données bdd.sqlite :

[1] TRUE
library(DBI)
library(RSQLite)
con <- DBI::dbConnect(RSQLite::SQLite(), dbname = "bdd.sqlite")
data(mtcars)
mtcars$name <- rownames(mtcars)
dbWriteTable(con, "mtcars", mtcars)
dbDisconnect(con)

Si on souhaite se connecter à cette base de données par la suite, on peut utiliser l’extension DBI, qui propose une interface générique entre **R// et différents systèmes de bases de données. On doit aussi avoir installé et chargé l’extension spécifique à notre base, ici RSQLite. On commence par ouvrir une connexion à l’aide de la fonction dbConnect de DBI :

library(DBI)
library(RSQLite)
con <- DBI::dbConnect(RSQLite::SQLite(), dbname = "bdd.sqlite")

La connexion est stockée dans un objet con, qu’on va utiliser à chaque fois qu’on voudra interroger la base.

On peut vérifier la liste des tables présentes et les champs de ces tables avec dbListTables et dbListFields :

dbListTables(con)
[1] "mtcars"
dbListFields(con, "mtcars")
 [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"  
 [9] "am"   "gear" "carb" "name"

On peut également lire le contenu d’une table dans un objet de notre environnement avec dbReadTable :

cars <- dbReadTable(con, "mtcars")

On peut également envoyer une requête SQL directement à la base et récupérer le résultat avec dbGetQuery :

dbGetQuery(con, "SELECT * FROM mtcars WHERE cyl = 4")

Enfin, quand on a terminé, on peut se déconnecter à l’aide de dbDisconnect :

dbDisconnect(con)

Ceci n’est évidemment qu’un tout petit aperçu des fonctionnalités de DBI.

Utilisation de dplyr et dbplyr

L’extension dplyr est dédiée à la manipulation de données, elle est présentée dans un chapitre dédié. En installant l’extension complémentaire dbplyr, on peut utiliser dplyr directement sur une connection à une base de données générée par DBI :

library(DBI)
library(RSQLite)
library(dplyr)
con <- DBI::dbConnect(RSQLite::SQLite(), dbname = "bdd.sqlite")

La fonction tbl notamment permet de créer un nouvel objet qui représente une table de la base de données :

cars_tbl <- tbl(con, "mtcars")

Ici l’objet cars_tbl n’est pas un tableau de données, c’est juste un objet permettant d’interroger la table de notre base de données.

On peut utiliser cet objet avec les verbes de dplyr :

cars_tbl %>%
  filter(cyl == 4) %>%
  select(name, mpg, cyl)

dbplyr s’occupe, de manière transparente, de transformer les instructions dplyr en requête SQL, d’interroger la base de données et de renvoyer le résultat. De plus, tout est fait pour qu’un minimum d’opérations sur la base, parfois coûteuses en temps de calcul, ne soient effectuées.

Il est possible de modifier des objets de type tbl, par exemple avec mutate :

cars_tbl <- cars_tbl %>% mutate(type = "voiture")

Dans ce cas la nouvelle colonne type est bien créée et on peut y accéder par la suite. Mais cette création se fait dans une table temporaire : elle n’existe que le temps de la connexion à la base de données. À la prochaine connexion, cette nouvelle colonne n’apparaîtra pas dans la table.

Bien souvent on utilisera une base de données quand les données sont trop volumineuses pour être gérées par un ordinateur de bureau. Mais si les données ne sont pas trop importantes, il sera toujours plus rapide de récupérer l’intégralité de la table dans notre session R pour pouvoir la manipuler comme les tableaux de données habituels. Ceci se fait grâce à la fonction collect de dplyr :

cars <- cars_tbl %>% collect()

Ici, cars est bien un tableau de données classique, copie de la table de la base au moment du collect.

Et dans tous les cas, on n’oubliera pas de se déconnecter avec :

dbDisconnect(con)

Ressources

Pour plus d’informations, voir la documentation très complète (en anglais) proposée par RStudio.

Par ailleurs, depuis la version 1.1, RStudio facilite la connexion à certaines bases de données grâce à l’onglet Connections. Pour plus d’informations on pourra se référer à l’article (en anglais) Using RStudio Connections.

Autres sources

R offre de très nombreuses autres possibilités pour accéder aux données. Il est ainsi possible d’importer des données depuis d’autres applications qui n’ont pas été évoquées (Epi Info, S-Plus, etc.), de lire des données via ODBC ou des connexions réseau, etc.

Pour plus d’informations on consultera le manuel R Data Import/Export :
http://cran.r-project.org/manuals.html.

La section Database Management du site Awesome R fournit également une liste d’extensions permettant de s’interfacer avec différents gestionnaires de bases de données.

Sauver ses données

R dispose également de son propre format pour sauvegarder et échanger des données. On peut sauver n’importe quel objet créé avec R et il est possible de sauver plusieurs objets dans un même fichier. L’usage est d’utiliser l’extension .RData pour les fichiers de données R. La fonction à utiliser s’appelle tout simplement save.

Par exemple, si l’on souhaite sauvegarder son tableau de données d ainsi que les objets tailles et poids dans un fichier export.RData :

save(d, tailles, poids, file = "export.RData")

À tout moment, il sera toujours possible de recharger ces données en mémoire à l’aide de la fonction load :

load("export.RData")

Si entre temps vous aviez modifié votre tableau d, vos modifications seront perdues. En effet, si lors du chargement de données, un objet du même nom existe en mémoire, ce dernier sera remplacé par l’objet importé.

La fonction save.image est un raccourci pour sauvergarder tous les objets de la session de travail dans le fichier .RData (un fichier un peu étrange car il n’a pas de nom mais juste une extension). Lors de la fermeture de RStudio, il vous sera demandé si vous souhaitez enregistrer votre session. Si vous répondez Oui, c’est cette fonction save.image qui sera appliquée.

save.image()
[1] FALSE

  1. L’option CSV fonctionne pour tous les fichiers de type texte, même si votre fichier a une autre extension, .txt par exemple

Où trouver de l’aide ?

La version originale de ce chapitre a été écrite par Julien Barnier dans le cadre du support de cours Introduction à R.

Aide en ligne

R dispose d’une aide en ligne très complète, mais dont l’usage n’est pas forcément très simple. D’une part car elle est intégralement en anglais, d’autre part car son organisation prend un certain temps à être maîtrisée.

Aide sur une fonction

La fonction la plus utile est sans doute help (ou son équivalent ?) qui permet d’afficher la page d’aide liée à une ou plusieurs fonctions. Celle-ci permet de lister les arguments de la fonction, d’avoir des informations détaillées sur son fonctionnement, les résultats qu’elle retourne, etc.

Pour accéder à l’aide de la fonction mean, par exemple, il vous suffit de saisir directement :

?mean

ou bien

help("mean")

Sous RStudio, la page d’aide correspondante s’affichera sous l’onglet Help dans le quadrant inférieur droit.

Chaque page d’aide comprend plusieurs sections, en particulier :

Section Contenu
Description donne un résumé en une phrase de ce que fait la fonction
Usage indique la ou les manières de l’utiliser
Arguments détaille tous les arguments possibles et leur signification
Value indique la forme du résultat renvoyé par la fonction
Details apporte des précisions sur le fonctionnement de la fonction
Note pour des remarques éventuelles
References pour des références bibliographiques ou des URL associées
See Also très utile, renvoie vers d’autres fonctions semblables ou liées, ce qui peut être très utile pour découvrir ou retrouver une fonction dont on a oublié le nom
Examples série d’exemples d’utilisation

Les exemples peuvent être directement exécutés en utilisant la fonction example :

example(mean)

mean> x <- c(0:10, 50)

mean> xm <- mean(x)

mean> c(xm, mean(x, trim = 0.10))
[1] 8.75 5.50

Naviguer dans l’aide

La fonction help.start permet d’afficher le sommaire de l’aide en ligne. Saisissez simplement :

help.start()

Si vous souhaitez rechercher quelque chose dans le contenu de l’aide, vous pouvez utiliser la fonction help.search (ou ?? qui est équivalente) qui renvoie une liste des pages d’aide contenant les termes recherchés.

Par exemple :

help.search("logistic")

ou

??logistic

pour rechercher les pages de l’aide qui contiennent le terme logistic.

Ressources sur le Web

De nombreuses ressources existent en ligne, mais la plupart sont en anglais.

Moteur de recherche

Le fait que le logiciel s’appelle R ne facilite malheureusement pas les recherches sur le Web… La solution à ce problème a été trouvée grâce à la constitution d’un moteur de recherche ad hoc à partir de Google, nommé Rseek :
http://www.rseek.org/.

Les requêtes saisies dans Rseek sont exécutées dans des corpus prédéfinis liés à R, notamment les documents et manuels, les listes de discussion ou le code source du programme.

Les requêtes devront cependant être formulées en anglais.

Aide en ligne

Le site R documentation propose un accès clair et rapide à la documentation de R et des extensions hébergées sur le CRAN (ainsi que certaines extensions hébergées sur GitHub). Il permet notamment de rechercher et naviguer facilement entre les pages des différentes fonctions :
http://www.rdocumentation.org/.

Ressources officielles

La documentation officielle de R est accessible en ligne depuis le site du projet :
http://www.r-project.org/.

Les liens de l’entrée Documentation du menu de gauche vous permettent d’accéder à différentes ressources.

Manuels

Les manuels sont des documents complets de présentation de certains aspects de R. Ils sont accessibles en ligne, ou téléchargeables au format PDF :
http://cran.r-project.org/manuals.html.

On notera plus particulièrement An introduction to R, normalement destiné aux débutants, mais qui nécessite quand même un minimum d’aisance en informatique et en statistiques :
http://cran.r-project.org/doc/manuals/R-intro.html.

R Data Import/Export explique notamment comment importer des données depuis d’autres logiciels :
http://cran.r-project.org/doc/manuals/R-data.html.

Ouvrages, blogs, MOOCs…

Francophones

Parmi les ressources en français, on peut citer notamment R et espace, manuel d’initiation à la programmation avec R appliqué à l’analyse de l’information géographique, librement téléchargeable en ligne.

La très bonne Introduction à R et au tidyverse de Julien Barnier disponible sur https://juba.github.io/tidyverse/.

La section Contributed documentation du site officiel de R contient également des liens vers différents documents en français, plus ou moins accessibles et plus ou moins récemment mis à jour.

Le pôle bioinformatique lyonnais (PBIL) propose depuis longtemps une somme très importante de documents, qui comprend des cours complets de statistiques utilisant R :

Plusieurs blogs francophones autour de R sont également actifs, parmi lesquels :

  • ElementR, le blog du groupe du même nom, qui propose de nombreuses ressources sur R en général et en particulier sur la cartographie ou l’analyse de réseaux.
  • R-atique, blog animé par Lise Vaudor, propose régulièrement des articles intéressants et accessibles sur des méthodes d’analyse ou sur des extensions R.

Enfin, le site France Université Numérique propose régulièrement des sessions de cours en ligne, parmi lesquels une Introduction à la statistique avec R et un cours sur l’Analyse des données multidimensionnelles.

On peut aussi citer :

Et enfin, une liste de ressources francophones : https://github.com/frrrenchies/frrrenchies/.

Anglophones

Les ressources anglophones sont évidemment très nombreuses.

On citera essentiellement l’ouvrage en ligne R for data science, très complet, et qui fournit une introduction très complète et progressive à R, et aux packages du tidyverse. Il existe également en version papier.

Pour aborder des aspects beaucoup plus avancés, l’ouvrage également en ligne Advanced R, d’Hadley Wickham, est extrêmement bien et fait et très complet.

On notera également l’existence du R journal, revue en ligne consacrée à R, et qui propose régulièrement des articles sur des méthodes d’analyse, des extensions, et l’actualité du langage.

La plateforme R-bloggers agrège les contenus de plusieurs centaines de blogs parlant de R, très pratique pour suivre l’actualité de la communauté.

Enfin, sur Twitter, les échanges autour de R sont regroupés autour du hashtag #rstats.

On peut aussi citer le site Awesome R (https://awesome-r.com/) qui fournit une liste d’extensions choisies et triées par thématique et le site [R Data Science Tutorials](https://github.com/ujjwalkarn/DataScienceR] qui recense des tutoriels en anglais.

FAQ

Les FAQ (frequently asked questions) regroupent des questions fréquemment posées et leurs réponses. À lire donc ou, au moins, à parcourir avant toute chose :
http://cran.r-project.org/faqs.html.

La FAQ la plus utile est la FAQ généraliste sur R :
http://cran.r-project.org/doc/FAQ/R-FAQ.html.

Mais il existe également une FAQ dédiée aux questions liées à Windows et une autre à la plateforme Mac OS X.

Les manuels et les FAQ sont accessibles même si vous n’avez pas d’accès à Internet en utilisant la fonction help.start décrite précédemment.

R-announce

R-announce est la liste de diffusion électronique officielle du projet. Elle ne comporte qu’un nombre réduit de messages (quelques-uns par mois tout au plus) et diffuse les annonces concernant de nouvelles versions de R ou d’autres informations particulièrement importantes. On peut s’y abonner à l’adresse suivante :
https://stat.ethz.ch/mailman/listinfo/r-announce

R Journal

R Journal est la « revue » officielle du projet R, qui a succédé début 2009 à la lettre de nouvelles R News. Elle paraît entre deux et cinq fois par an et contient des informations sur les nouvelles versions du logiciel, des articles présentant des extensions, des exemples d’analyse… Les parutions sont annoncées sur la liste de diffusion R-announce et les numéros sont téléchargeables à l’adresse suivante :
http://journal.r-project.org/.

Autres documents

On trouvera de nombreux documents dans différentes langues, en général au format PDF, dans le répertoire suivant :
http://cran.r-project.org/doc/contrib/.

Parmi ceux-ci, les cartes de référence peuvent être très utiles, ce sont des aides-mémoire recensant les fonctions les plus courantes :
http://cran.r-project.org/doc/contrib/Short-refcard.pdf

On notera également un document d’introduction en anglais progressif et s’appuyant sur des méthodes statistiques relativement simples :
http://cran.r-project.org/doc/contrib/Verzani-SimpleR.pdf

Pour les utilisateurs déjà habitués à SAS ou SPSS, le livre R for SAS and SPSS Users et le document gratuit qui en est tiré peuvent être de bonnes ressources, tout comme le site web Quick-R :
http://rforsasandspssusers.com/ et http://www.statmethods.net/.

Revue

La revue Journal of Statistical Software est une revue électronique anglophone, dont les articles sont en accès libre, et qui traite de l’utilisation de logiciels d’analyse de données dans un grand nombre de domaines. De nombreux articles (la majorité) sont consacrés à R et à la présentation d’extensions plus ou moins spécialisées.

Les articles qui y sont publiés prennent souvent la forme de tutoriels plus ou moins accessibles mais qui fournissent souvent une bonne introduction et une ressource riche en informations et en liens.

Adresse de la revue :
http://www.jstatsoft.org/

Ressources francophones

Il existe des ressources en français sur l’utilisation de R, mais peu sont réellement destinées aux débutants, elles nécessitent en général des bases à la fois en informatique et en statistique.

Le document le plus abordable et le plus complet est sans doute R pour les débutants, d’Emmanuel Paradis, accessible au format PDF :
http://cran.r-project.org/doc/contrib/Paradis-rdebuts_fr.pdf.

La somme de documentation en français la plus importante liée à R est sans nulle doute celle mise à disposition par le Pôle bioinformatique lyonnais. Leur site propose des cours complets de statistique utilisant R :
http://pbil.univ-lyon1.fr/R/enseignement.html.

La plupart des documents sont assez pointus niveau mathématique et plutôt orientés biostatistique, mais on trouvera des documents plus introductifs ici :
http://pbil.univ-lyon1.fr/R/html/cours1.

Dans tous les cas la somme de travail et de connaissances mise à disposition librement est impressionnante… Enfin, le site de Vincent Zoonekynd (http://zoonek2.free.fr/UNIX/48_R_2004/all.html) comprend de nombreuses notes prises au cours de sa découverte du logiciel. On notera cependant que l’auteur est normalien et docteur en mathématiques…

RStudio

La documentation officielle de RStudio est disponible sur https://support.rstudio.com (catégorie Documentation disponible en milieu de page).

Antisèches (cheatsheet)

On peut trouver un peu partout sur internet des antisèches (cheatsheets en anglais) qui sont en général un fichier PDF résumant les principales fonctions d’une extension ou d’une problématique donnée. Ces antisèches peuvent être imprimées afin de les avoir facilement à porter de main.

Pour les trouver, il suffit d’effectuer une recherche Google avec les mots-clés R cheatsheet ou <pkg> cheatsheet en remplacant <pkg> par le nom du package qui nous intéresse.

Certaines sont également disponibles directement dans RStudio, dans le menu Help > Cheatsheets.

Où poser des questions ?

La communauté des utilisateurs de R est très active et en général très contente de pouvoir répondre aux questions (nombreuses) des débutants et à celles (tout aussi nombreuses) des utilisateurs plus expérimentés. Dans tous les cas, les règles de base à respecter avant de poser une question sont toujours les mêmes : avoir cherché soi-même la réponse auparavant, notamment dans les FAQ et dans l’aide en ligne, et poser sa question de la manière la plus claire possible, de préférence avec un exemple de code posant problème.

Les forums d’analyse-R

En premier lieu (autopromotion oblige), chaque chapitre du site d’analyse-R (http://larmarange.github.io/analyse-R/) comporte en bas de page une fonctionnalité permettant de laisser des commentaires. On peut donc y poser une question en lien avec le chapitre concerné.

Liste R-soc

Une liste de discussion a été créée spécialement pour permettre aide et échanges autour de l’utilisation de R en sciences sociales. Elle est hébergée par RENATER et on peut s’y abonner à l’adresse suivante :
https://groupes.renater.fr/sympa/subscribe/r-soc.

Grâce aux services offerts par le site gmane.org, la liste est également disponible sous d’autres formes (forum Web, blog, NNTP, flux RSS) permettant de lire et de poster sans avoir à s’inscrire et à recevoir les messages sous forme de courrier électronique. Pour plus d’informations :
http://dir.gmane.org/gmane.comp.lang.r.user.french.

StackOverflow

Le site StackOverflow (qui fait partie de la famille des sites StackExchange) comprend une section (anglophone) dédiée à R qui permet de poser des questions et en général d’obtenir des réponses assez rapidement :
http://stackoverflow.com/questions/tagged/r.

La première chose à faire, évidemment, est de vérifier que sa question n’a pas déjà été posée.

Forum Web en français

Le Cirad a mis en ligne un forum dédié aux utilisateurs de R, très actif :
http://forums.cirad.fr/logiciel-R/index.php.

Les questions diverses et variées peuvent être posées dans la rubrique Questions en cours :
http://forums.cirad.fr/logiciel-R/viewforum.php?f=3.

Il est tout de même conseillé de faire une recherche rapide sur le forum avant de poser une question, pour voir si la réponse ne s’y trouverait pas déjà.

Canaux IRC (chat)

L’IRC, ou Internet Relay Chat est le vénérable ancêtre toujours très actif des messageries instantanées actuelles. Un canal (en anglais) est notamment dédié aux échanges autour de R (#R).

Si vous avez déjà l’habitude d’utiliser IRC, il vous suffit de pointer votre client préféré sur Freenode (irc.freenode.net) puis de rejoindre l’un des canaux en question.

Sinon, le plus simple est certainement d’utiliser l’interface web de Mibbit, accessible à l’adresse http://www.mibbit.com/.

Dans le champ Connect to IRC, sélectionnez Freenode.net, puis saisissez un pseudonyme dans le champ Nick et #R dans le champ Channel. Vous pourrez alors discuter directement avec les personnes présentes.

Le canal #R est normalement peuplé de personnes qui seront très heureuses de répondre à toutes les questions, et en général l’ambiance y est très bonne. Une fois votre question posée, n’hésitez pas à être patient et à attendre quelques minutes, voire quelques heures, le temps qu’un des habitués vienne y faire un tour.

Listes de discussion officielles

La liste de discussion d’entraide (par courrier électronique) officielle du logiciel R s’appelle R-help. On peut s’y abonner à l’adresse suivante, mais il s’agit d’une liste avec de nombreux messages :
https://stat.ethz.ch/mailman/listinfo/r-help.

Pour une consultation ou un envoi ponctuels, le mieux est sans doute d’utiliser les interfaces Web fournies par gmane.org :
http://blog.gmane.org/gmane.comp.lang.r.general.

R-help est une liste avec de nombreux messages, suivie par des spécialistes de R, dont certains des développeurs principaux. Elle est cependant à réserver aux questions particulièrement techniques qui n’ont pas trouvé de réponses par d’autres biais.

Dans tous les cas, il est nécessaire avant de poster sur cette liste de bien avoir pris connaissance du posting guide correspondant :
http://www.r-project.org/posting-guide.html.

Plusieurs autres listes plus spécialisées existent également, elles sont listées à l’adresse suivante :
http://www.r-project.org/mail.html.

Visualiser ses données

Au fil des différents chapitres, nous avons abordé diverses fonctions utiles au quotidien et permettant de visualiser ses données. Ce chapitre se propose de les regrouper.

Chargeons tout d’abord quelques fichiers de données à titre d’exemple.

library(questionr)
data(hdv2003)
data(rp99)
data(fecondite)

Inspection visuelle des données

La particularité de R par rapport à d’autres logiciels comme Modalisa ou SPSS est de ne pas proposer, par défaut, de vue des données sous forme de tableau. Ceci peut parfois être un peu déstabilisant dans les premiers temps d’utilisation, même si l’on perd vite l’habitude et qu’on finit par se rendre compte que « voir » les données n’est pas forcément un gage de productivité ou de rigueur dans le traitement.

Néanmoins, R propose une interface permettant de visualiser le contenu d’un tableau de données à l’aide de la fonction View :

View(hdv2003)

Sous RStudio, on peut aussi afficher la visionneusee (viewer) en cliquant sur la petite icône en forme de tableau située à droite de la ligne d’un tableau de données dans l’onglet Environment du quadrant supérieur droit (cf. figure ci-après).

Icône pour afficher une vue du contenu d’un tableau
Icône pour afficher une vue du contenu d’un tableau

Dans tous les cas, RStudio lancera le viewer dans un onglet dédié dans le quadrant supérieur gauche. Le visualiseur de RStudio est plus avancé que celui-de base fournit par R. Il est possible de trier les données selon une variable en cliquant sur le nom de cette dernière. Il y a également un champs de recherche et un bouton Filter donnant accès à des options de filtrage avancées.

La visionneuse de données de RStudio
La visionneuse de données de RStudio

summary

La fonction summary permet d’avoir une vue résumée d’une variable. Elle s’applique à tout type d’objets (y compris un tableau de données entier) et s’adapte à celui-ci.

summary(hdv2003$age)
Min. 1st Qu. Median Mean 3rd Qu. Max.
18 35 48 48.157 60 97
summary(hdv2003$qualif)
      Ouvrier specialise         Ouvrier qualifie 
                     203                      292 
              Technicien Profession intermediaire 
                      86                      160 
                   Cadre                  Employe 
                     260                      594 
                   Autre                     NA's 
                      58                      347 
summary(hdv2003)
id age sexe nivetud poids occup qualif freres.soeurs clso relig trav.imp trav.satisf hard.rock lecture.bd peche.chasse cuisine bricol cinema sport heures.tv
Min. : 1.0 Min. :18.00 Homme: 899 Enseignement technique ou professionnel court :463 Min. : 78.08 Exerce une profession:1049 Employe :594 Min. : 0.000 Oui : 936 Pratiquant regulier :266 Le plus important : 29 Satisfaction :480 Non:1986 Non:1953 Non:1776 Non:1119 Non:1147 Non:1174 Non:1277 Min. : 0.000
1st Qu.: 500.8 1st Qu.:35.00 Femme:1101 Enseignement superieur y compris technique superieur:441 1st Qu.: 2221.82 Chomeur : 134 Ouvrier qualifie :292 1st Qu.: 1.000 Non :1037 Pratiquant occasionnel :442 Aussi important que le reste:259 Insatisfaction:117 Oui: 14 Oui: 47 Oui: 224 Oui: 881 Oui: 853 Oui: 826 Oui: 723 1st Qu.: 1.000
Median :1000.5 Median :48.00 NA Derniere annee d’etudes primaires :341 Median : 4631.19 Etudiant, eleve : 94 Cadre :260 Median : 2.000 Ne sait pas: 27 Appartenance sans pratique :760 Moins important que le reste:708 Equilibre :451 NA NA NA NA NA NA NA Median : 2.000
Mean :1000.5 Mean :48.16 NA 1er cycle :204 Mean : 5535.61 Retraite : 392 Ouvrier specialise :203 Mean : 3.283 NA Ni croyance ni appartenance:399 Peu important : 52 NA’s :952 NA NA NA NA NA NA NA Mean : 2.247
3rd Qu.:1500.2 3rd Qu.:60.00 NA 2eme cycle :183 3rd Qu.: 7626.53 Retire des affaires : 77 Profession intermediaire:160 3rd Qu.: 5.000 NA Rejet : 93 NA’s :952 NA NA NA NA NA NA NA NA 3rd Qu.: 3.000
Max. :2000.0 Max. :97.00 NA (Other) :256 Max. :31092.14 Au foyer : 171 (Other) :144 Max. :22.000 NA NSP ou NVPR : 40 NA NA NA NA NA NA NA NA NA Max. :12.000
NA NA NA NA’s :112 NA Autre inactif : 83 NA’s :347 NA NA NA NA NA NA NA NA NA NA NA NA NA’s :5

str

La fonction str est plus complète que names. Elle liste les différentes variables, indique leur type et donne le cas échéant des informations supplémentaires ainsi qu’un échantillon des premières valeurs prises par cette variable :

str(hdv2003)
'data.frame':   2000 obs. of  20 variables:
 $ id           : int  1 2 3 4 5 6 7 8 9 10 ...
 $ age          : int  28 23 59 34 71 35 60 47 20 28 ...
 $ sexe         : Factor w/ 2 levels "Homme","Femme": 2 2 1 1 2 2 2 1 2 1 ...
 $ nivetud      : Factor w/ 8 levels "N'a jamais fait d'etudes",..: 8 NA 3 8 3 6 3 6 NA 7 ...
 $ poids        : num  2634 9738 3994 5732 4329 ...
 $ occup        : Factor w/ 7 levels "Exerce une profession",..: 1 3 1 1 4 1 6 1 3 1 ...
 $ qualif       : Factor w/ 7 levels "Ouvrier specialise",..: 6 NA 3 3 6 6 2 2 NA 7 ...
 $ freres.soeurs: int  8 2 2 1 0 5 1 5 4 2 ...
 $ clso         : Factor w/ 3 levels "Oui","Non","Ne sait pas": 1 1 2 2 1 2 1 2 1 2 ...
 $ relig        : Factor w/ 6 levels "Pratiquant regulier",..: 4 4 4 3 1 4 3 4 3 2 ...
 $ trav.imp     : Factor w/ 4 levels "Le plus important",..: 4 NA 2 3 NA 1 NA 4 NA 3 ...
 $ trav.satisf  : Factor w/ 3 levels "Satisfaction",..: 2 NA 3 1 NA 3 NA 2 NA 1 ...
 $ hard.rock    : Factor w/ 2 levels "Non","Oui": 1 1 1 1 1 1 1 1 1 1 ...
 $ lecture.bd   : Factor w/ 2 levels "Non","Oui": 1 1 1 1 1 1 1 1 1 1 ...
 $ peche.chasse : Factor w/ 2 levels "Non","Oui": 1 1 1 1 1 1 2 2 1 1 ...
 $ cuisine      : Factor w/ 2 levels "Non","Oui": 2 1 1 2 1 1 2 2 1 1 ...
 $ bricol       : Factor w/ 2 levels "Non","Oui": 1 1 1 2 1 1 1 2 1 1 ...
 $ cinema       : Factor w/ 2 levels "Non","Oui": 1 2 1 2 1 2 1 1 2 2 ...
 $ sport        : Factor w/ 2 levels "Non","Oui": 1 2 2 2 1 2 1 1 1 2 ...
 $ heures.tv    : num  0 1 0 2 3 2 2.9 1 2 2 ...

La fonction str est essentielle à connaître et peut s’appliquer à n’importe quel type d’objet. C’est un excellent moyen de connaître en détail la structure d’un objet. Cependant, les résultats peuvent être parfois trop détaillés et on lui priviligiera dans certains cas les fonctions suivantes.

glimpse (dplyr)

L’extension dplyr (voir le chapitre dédié), propose une fonction glimpse (ce qui signifie aperçu en anglais) qui permet de visualiser rapidement et de manière condensée le contenu d’un tableau de données.

library(dplyr)
glimpse(hdv2003)
Rows: 2,000
Columns: 20
$ id            <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11...
$ age           <int> 28, 23, 59, 34, 71, 35, 60, 47, 2...
$ sexe          <fct> Femme, Femme, Homme, Homme, Femme...
$ nivetud       <fct> "Enseignement superieur y compris...
$ poids         <dbl> 2634.3982, 9738.3958, 3994.1025, ...
$ occup         <fct> "Exerce une profession", "Etudian...
$ qualif        <fct> Employe, NA, Technicien, Technici...
$ freres.soeurs <int> 8, 2, 2, 1, 0, 5, 1, 5, 4, 2, 3, ...
$ clso          <fct> Oui, Oui, Non, Non, Oui, Non, Oui...
$ relig         <fct> Ni croyance ni appartenance, Ni c...
$ trav.imp      <fct> Peu important, NA, Aussi importan...
$ trav.satisf   <fct> Insatisfaction, NA, Equilibre, Sa...
$ hard.rock     <fct> Non, Non, Non, Non, Non, Non, Non...
$ lecture.bd    <fct> Non, Non, Non, Non, Non, Non, Non...
$ peche.chasse  <fct> Non, Non, Non, Non, Non, Non, Oui...
$ cuisine       <fct> Oui, Non, Non, Oui, Non, Non, Oui...
$ bricol        <fct> Non, Non, Non, Oui, Non, Non, Non...
$ cinema        <fct> Non, Oui, Non, Oui, Non, Oui, Non...
$ sport         <fct> Non, Oui, Oui, Oui, Non, Oui, Non...
$ heures.tv     <dbl> 0.0, 1.0, 0.0, 2.0, 3.0, 2.0, 2.9...

look_for (labelled)

L’extension labelled propose une fonction look_for, inspirée de Stata, qui permet de lister les différentes variables d’un fichier de données, ainsi que leurs principales caractéristiques :

library(labelled)
look_for(hdv2003)
pos   variable      label col_type values                                                         
<chr> <chr>         <chr> <chr>    <chr>                                                          
1     id            —     int      range: 1 - 2000                                                
2     age           —     int      range: 18 - 97                                                 
3     sexe          —     fct      Homme                                                          
                                   Femme                                                          
4     nivetud       —     fct      N'a jamais fait d'etudes                                       
                                   A arrete ses etudes, avant la derniere annee d'etudes primaires
                                   Derniere annee d'etudes primaires                              
                                   1er cycle                                                      
                                   2eme cycle                                                     
                                   Enseignement technique ou professionnel court                  
                                   Enseignement technique ou professionnel long                   
                                   Enseignement superieur y compris technique superieur           
5     poids         —     dbl      range: 78.0783403 - 31092.14132                                
6     occup         —     fct      Exerce une profession                                          
                                   Chomeur                                                        
                                   Etudiant, eleve                                                
                                   Retraite                                                       
                                   Retire des affaires                                            
                                   Au foyer                                                       
                                   Autre inactif                                                  
7     qualif        —     fct      Ouvrier specialise                                             
                                   Ouvrier qualifie                                               
                                   Technicien                                                     
                                   Profession intermediaire                                       
                                   Cadre                                                          
                                   Employe                                                        
                                   Autre                                                          
8     freres.soeurs —     int      range: 0 - 22                                                  
9     clso          —     fct      Oui                                                            
                                   Non                                                            
                                   Ne sait pas                                                    
10    relig         —     fct      Pratiquant regulier                                            
                                   Pratiquant occasionnel                                         
                                   Appartenance sans pratique                                     
                                   Ni croyance ni appartenance                                    
                                   Rejet                                                          
                                   NSP ou NVPR                                                    
11    trav.imp      —     fct      Le plus important                                              
                                   Aussi important que le reste                                   
                                   Moins important que le reste                                   
                                   Peu important                                                  
12    trav.satisf   —     fct      Satisfaction                                                   
                                   Insatisfaction                                                 
                                   Equilibre                                                      
13    hard.rock     —     fct      Non                                                            
                                   Oui                                                            
14    lecture.bd    —     fct      Non                                                            
                                   Oui                                                            
15    peche.chasse  —     fct      Non                                                            
                                   Oui                                                            
16    cuisine       —     fct      Non                                                            
                                   Oui                                                            
17    bricol        —     fct      Non                                                            
                                   Oui                                                            
18    cinema        —     fct      Non                                                            
                                   Oui                                                            
19    sport         —     fct      Non                                                            
                                   Oui                                                            
20    heures.tv     —     dbl      range: 0 - 12   

Lorsque l’on a un gros tableau de données avec de nombreuses variables, il peut être difficile de retrouver la ou les variables d’intérêt. Il est possible d’indiquer à look_for un mot-clé pour limiter la recherche. Par exemple :

look_for(hdv2003, "trav")
pos   variable    label col_type values                      
<chr> <chr>       <chr> <chr>    <chr>                       
11    trav.imp    —     fct      Le plus important           
                                 Aussi important que le reste
                                 Moins important que le reste
                                 Peu important               
12    trav.satisf —     fct      Satisfaction                
                                 Insatisfaction              
                                 Equilibre 

Il est à noter que si la recherche n’est pas sensible à la casse (i.e. aux majuscules et aux minuscules), elle est sensible aux accents. Il est aussi possible de fournir plusieurs expressions de recherche.

La fonction look_for est par ailleurs compatible avec les étiquettes de variable de l’extension labelled, les étiquettes étant prise en compte dans la recherche d’une variable.

look_for(femmes, "rés")
pos   variable label               col_type values    
<chr> <chr>    <chr>               <chr>    <chr>     
7     milieu   Milieu de résidence dbl+lbl  [1] urbain
                                            [2] rural 
8     region   Région de résidence dbl+lbl  [1] Nord  
                                            [2] Est   
                                            [3] Sud   
                                            [4] Ouest
look_for(femmes, "rés", "nb")
pos   variable     label                  col_type values          
<chr> <chr>        <chr>                  <chr>    <chr>           
7     milieu       Milieu de résidence    dbl+lbl  [1] urbain      
                                                   [2] rural       
8     region       Région de résidence    dbl+lbl  [1] Nord        
                                                   [2] Est         
                                                   [3] Sud         
                                                   [4] Ouest       
16    nb_enf_ideal Nombre idéal d'enfants dbl+lbl  [96] Ne sait pas
                                                   [99] manquant   

À noter, le résultat renvoyé par look_for est un tableau de données qui peut ensuite être aisément manipulé (voir l’aide de la fonction).

describe (questionr)

L’extension questionr fournit également une fonction bien pratique pour décrire les différentes variables d’un tableau de données. Il s’agit de describe. Faisons de suite un essai :

describe(hdv2003)
[2000 obs. x 20 variables] tbl_df tbl data.frame

$id: 
integer: 1 2 3 4 5 6 7 8 9 10 ...
min: 1 - max: 2000 - NAs: 0 (0%) - 2000 unique values

$age: 
integer: 28 23 59 34 71 35 60 47 20 28 ...
min: 18 - max: 97 - NAs: 0 (0%) - 78 unique values

$sexe: 
nominal factor: "Femme" "Femme" "Homme" "Homme" "Femme" "Femme" "Femme" "Homme" "Femme" "Homme" ...
2 levels: Homme | Femme
NAs: 0 (0%)

$nivetud: 
nominal factor: "Enseignement superieur y compris technique superieur" NA "Derniere annee d'etudes primaires" "Enseignement superieur y compris technique superieur" "Derniere annee d'etudes primaires" "Enseignement technique ou professionnel court" "Derniere annee d'etudes primaires" "Enseignement technique ou professionnel court" NA "Enseignement technique ou professionnel long" ...
8 levels: N'a jamais fait d'etudes | A arrete ses etudes, avant la derniere annee d'etudes primaires | Derniere annee d'etudes primaires | 1er cycle | 2eme cycle | Enseignement technique ou professionnel court | Enseignement technique ou professionnel long | Enseignement superieur y compris technique superieur
NAs: 112 (5.6%)

$poids: 
numeric: 2634.3982157 9738.3957759 3994.1024587 5731.6615081 4329.0940022 8674.6993828 6165.8034861 12891.640759 7808.8720636 2277.160471 ...
min: 78.0783403 - max: 31092.14132 - NAs: 0 (0%) - 1877 unique values

$occup: 
nominal factor: "Exerce une profession" "Etudiant, eleve" "Exerce une profession" "Exerce une profession" "Retraite" "Exerce une profession" "Au foyer" "Exerce une profession" "Etudiant, eleve" "Exerce une profession" ...
7 levels: Exerce une profession | Chomeur | Etudiant, eleve | Retraite | Retire des affaires | Au foyer | Autre inactif
NAs: 0 (0%)

$qualif: 
nominal factor: "Employe" NA "Technicien" "Technicien" "Employe" "Employe" "Ouvrier qualifie" "Ouvrier qualifie" NA "Autre" ...
7 levels: Ouvrier specialise | Ouvrier qualifie | Technicien | Profession intermediaire | Cadre | Employe | Autre
NAs: 347 (17.3%)

$freres.soeurs: 
integer: 8 2 2 1 0 5 1 5 4 2 ...
min: 0 - max: 22 - NAs: 0 (0%) - 19 unique values

$clso: 
nominal factor: "Oui" "Oui" "Non" "Non" "Oui" "Non" "Oui" "Non" "Oui" "Non" ...
3 levels: Oui | Non | Ne sait pas
NAs: 0 (0%)

$relig: 
nominal factor: "Ni croyance ni appartenance" "Ni croyance ni appartenance" "Ni croyance ni appartenance" "Appartenance sans pratique" "Pratiquant regulier" "Ni croyance ni appartenance" "Appartenance sans pratique" "Ni croyance ni appartenance" "Appartenance sans pratique" "Pratiquant occasionnel" ...
6 levels: Pratiquant regulier | Pratiquant occasionnel | Appartenance sans pratique | Ni croyance ni appartenance | Rejet | NSP ou NVPR
NAs: 0 (0%)

$trav.imp: 
nominal factor: "Peu important" NA "Aussi important que le reste" "Moins important que le reste" NA "Le plus important" NA "Peu important" NA "Moins important que le reste" ...
4 levels: Le plus important | Aussi important que le reste | Moins important que le reste | Peu important
NAs: 952 (47.6%)

$trav.satisf: 
nominal factor: "Insatisfaction" NA "Equilibre" "Satisfaction" NA "Equilibre" NA "Insatisfaction" NA "Satisfaction" ...
3 levels: Satisfaction | Insatisfaction | Equilibre
NAs: 952 (47.6%)

$hard.rock: 
nominal factor: "Non" "Non" "Non" "Non" "Non" "Non" "Non" "Non" "Non" "Non" ...
2 levels: Non | Oui
NAs: 0 (0%)

$lecture.bd: 
nominal factor: "Non" "Non" "Non" "Non" "Non" "Non" "Non" "Non" "Non" "Non" ...
2 levels: Non | Oui
NAs: 0 (0%)

$peche.chasse: 
nominal factor: "Non" "Non" "Non" "Non" "Non" "Non" "Oui" "Oui" "Non" "Non" ...
2 levels: Non | Oui
NAs: 0 (0%)

$cuisine: 
nominal factor: "Oui" "Non" "Non" "Oui" "Non" "Non" "Oui" "Oui" "Non" "Non" ...
2 levels: Non | Oui
NAs: 0 (0%)

$bricol: 
nominal factor: "Non" "Non" "Non" "Oui" "Non" "Non" "Non" "Oui" "Non" "Non" ...
2 levels: Non | Oui
NAs: 0 (0%)

$cinema: 
nominal factor: "Non" "Oui" "Non" "Oui" "Non" "Oui" "Non" "Non" "Oui" "Oui" ...
2 levels: Non | Oui
NAs: 0 (0%)

$sport: 
nominal factor: "Non" "Oui" "Oui" "Oui" "Non" "Oui" "Non" "Non" "Non" "Oui" ...
2 levels: Non | Oui
NAs: 0 (0%)

$heures.tv: 
numeric: 0 1 0 2 3 2 2.9 1 2 2 ...
min: 0 - max: 12 - NAs: 5 (0.2%) - 30 unique values

Comme on le voit sur cet exemple, describe nous affiche le type des variables, les premières valeurs de chacune, le nombre de valeurs manquantes, le nombre de valeurs différentes (uniques) ainsi que quelques autres informations suivant le type de variables.

Il est possible de restreindre l’affichage à seulement quelques variables en indiquant le nom de ces dernières ou une expression de recherche (comme avec lookfor).

describe(hdv2003, "age", "trav")
[2000 obs. x 20 variables] tbl_df tbl data.frame

$age: 
integer: 28 23 59 34 71 35 60 47 20 28 ...
min: 18 - max: 97 - NAs: 0 (0%) - 78 unique values

$trav.imp: 
nominal factor: "Peu important" NA "Aussi important que le reste" "Moins important que le reste" NA "Le plus important" NA "Peu important" NA "Moins important que le reste" ...
4 levels: Le plus important | Aussi important que le reste | Moins important que le reste | Peu important
NAs: 952 (47.6%)

$trav.satisf: 
nominal factor: "Insatisfaction" NA "Equilibre" "Satisfaction" NA "Equilibre" NA "Insatisfaction" NA "Satisfaction" ...
3 levels: Satisfaction | Insatisfaction | Equilibre
NAs: 952 (47.6%)

On peut également transmettre juste une variable :

describe(hdv2003$sexe)
[2000 obs.] 
nominal factor: "Femme" "Femme" "Homme" "Homme" "Femme" "Femme" "Femme" "Homme" "Femme" "Homme" ...
2 levels: Homme | Femme
NAs: 0 (0%)

         n   %
Homme  899  45
Femme 1101  55
Total 2000 100

Enfin, describe est également compatible avec les vecteurs labellisés.

describe(femmes, "milieu")
[2000 obs. x 17 variables] tbl_df tbl data.frame

$milieu: Milieu de résidence
labelled double: 2 2 2 2 2 2 2 2 2 2 ...
min: 1 - max: 2 - NAs: 0 (0%) - 2 unique values
2 value labels: [1] urbain [2] rural

À noter, l’argument freq.n.max permets d’indiquer le nombre de modalités en-dessous duquel describe renverra également un tri à plat de la variable.

describe(menages, freq.n.max = 6)
[1814 obs. x 5 variables] tbl_df tbl data.frame

$id_menage: Identifiant du ménage
numeric: 1 2 3 4 5 6 7 8 9 10 ...
min: 1 - max: 1814 - NAs: 0 (0%) - 1814 unique values

$taille: Taille du ménage (nombre de membres)
numeric: 7 3 6 5 7 6 15 6 5 19 ...
min: 1 - max: 31 - NAs: 0 (0%) - 30 unique values

$sexe_chef: Sexe du chef de ménage
labelled double: 2 1 1 1 1 2 2 2 1 1 ...
min: 1 - max: 2 - NAs: 0 (0%) - 2 unique values
2 value labels: [1] homme [2] femme

             n     %
[1] homme 1420  78.3
[2] femme  394  21.7
Total     1814 100.0

$structure: Structure démographique du ménage
labelled double: 4 2 5 4 4 4 5 2 5 5 ...
min: 1 - max: 5 - NAs: 0 (0%) - 5 unique values
6 value labels: [0] pas d'adulte [1] un adulte [2] deux adultes de sexe opposé [3] deux adultes de même sexe [4] trois adultes ou plus avec lien de parenté [5] adultes sans lien de parenté

                                                  n     %
[0] pas d'adulte                                  0   0.0
[1] un adulte                                    78   4.3
[2] deux adultes de sexe opposé                 439  24.2
[3] deux adultes de même sexe                    75   4.1
[4] trois adultes ou plus avec lien de parenté  920  50.7
[5] adultes sans lien de parenté                302  16.6
Total                                          1814 100.0

$richesse: Niveau de vie (quintiles)
labelled double: 1 2 2 1 1 3 2 5 4 3 ...
min: 1 - max: 5 - NAs: 0 (0%) - 5 unique values
5 value labels: [1] très pauvre [2] pauvre [3] moyen [4] riche [5] très riche

                   n     %
[1] très pauvre  335  18.5
[2] pauvre       357  19.7
[3] moyen        402  22.2
[4] riche        350  19.3
[5] très riche   370  20.4
Total           1814 100.0

Addins de codebook

L’extension codebook fournit plusieurs addins permettant d’explorer les étiquettes des différentes variables d’un tableau de données. Ils sont accessibles par le menu Addins de RStudio.

On peut aussi lancer les addins manuellement, par exemple avec la commande suivante :

codebook::label_browser_static(femmes)

skim (skimr)

L’extension skimr a pour objectif de fournir une fonction skim comme alternative à summary{base} pour les vecteurs et les tableaux de données afin de fournir plus de statistiques dans un format plus compact. Elle peut être appliquée à un vecteur donné ou directement à un tableau de données.

library(skimr)
skim(hdv2003$cuisine)
Data summary
Name hdv2003$cuisine
Number of rows 2000
Number of columns 1
_______________________
Column type frequency:
factor 1
________________________
Group variables None

Variable type: factor

skim_variable n_missing complete_rate ordered n_unique top_counts
data 0 1 FALSE 2 Non: 1119, Oui: 881
skim(hdv2003)
Data summary
Name hdv2003
Number of rows 2000
Number of columns 20
_______________________
Column type frequency:
factor 15
numeric 5
________________________
Group variables None

Variable type: factor

skim_variable n_missing complete_rate ordered n_unique top_counts
sexe 0 1.00 FALSE 2 Fem: 1101, Hom: 899
nivetud 112 0.94 FALSE 8 Ens: 463, Ens: 441, Der: 341, 1er: 204
occup 0 1.00 FALSE 7 Exe: 1049, Ret: 392, Au : 171, Cho: 134
qualif 347 0.83 FALSE 7 Emp: 594, Ouv: 292, Cad: 260, Ouv: 203
clso 0 1.00 FALSE 3 Non: 1037, Oui: 936, Ne : 27
relig 0 1.00 FALSE 6 App: 760, Pra: 442, Ni : 399, Pra: 266
trav.imp 952 0.52 FALSE 4 Moi: 708, Aus: 259, Peu: 52, Le : 29
trav.satisf 952 0.52 FALSE 3 Sat: 480, Equ: 451, Ins: 117
hard.rock 0 1.00 FALSE 2 Non: 1986, Oui: 14
lecture.bd 0 1.00 FALSE 2 Non: 1953, Oui: 47
peche.chasse 0 1.00 FALSE 2 Non: 1776, Oui: 224
cuisine 0 1.00 FALSE 2 Non: 1119, Oui: 881
bricol 0 1.00 FALSE 2 Non: 1147, Oui: 853
cinema 0 1.00 FALSE 2 Non: 1174, Oui: 826
sport 0 1.00 FALSE 2 Non: 1277, Oui: 723

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
id 0 1 1000.50 577.49 1.00 500.75 1000.50 1500.25 2000.00 <U+2587><U+2587><U+2587><U+2587><U+2587>
age 0 1 48.16 16.94 18.00 35.00 48.00 60.00 97.00 <U+2586><U+2587><U+2587><U+2585><U+2581>
poids 0 1 5535.61 4375.03 78.08 2221.82 4631.19 7626.54 31092.14 <U+2587><U+2583><U+2581><U+2581><U+2581>
freres.soeurs 0 1 3.28 2.77 0.00 1.00 2.00 5.00 22.00 <U+2587><U+2582><U+2581><U+2581><U+2581>
heures.tv 5 1 2.25 1.78 0.00 1.00 2.00 3.00 12.00 <U+2587><U+2583><U+2581><U+2581><U+2581>

On peut noter que les variables sont regroupées par type.

Il est possible de sélectionner des variables à la manière de dplyr. Voir l’aide de contains.

skim(hdv2003, contains("re"))
Data summary
Name hdv2003
Number of rows 2000
Number of columns 20
_______________________
Column type frequency:
factor 2
numeric 2
________________________
Group variables None

Variable type: factor

skim_variable n_missing complete_rate ordered n_unique top_counts
relig 0 1 FALSE 6 App: 760, Pra: 442, Ni : 399, Pra: 266
lecture.bd 0 1 FALSE 2 Non: 1953, Oui: 47

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
freres.soeurs 0 1 3.28 2.77 0 1 2 5 22 <U+2587><U+2582><U+2581><U+2581><U+2581>
heures.tv 5 1 2.25 1.78 0 1 2 3 12 <U+2587><U+2583><U+2581><U+2581><U+2581>

Le support des vecteurs labellisés est encore en cours d’intégration.

skim(menages)
Warning: Couldn't find skimmers for class: haven_labelled,
vctrs_vctr, double, numeric; No user-defined `sfl` provided.
Falling back to `character`.

Warning: Couldn't find skimmers for class: haven_labelled,
vctrs_vctr, double, numeric; No user-defined `sfl` provided.
Falling back to `character`.

Warning: Couldn't find skimmers for class: haven_labelled,
vctrs_vctr, double, numeric; No user-defined `sfl` provided.
Falling back to `character`.
Data summary
Name menages
Number of rows 1814
Number of columns 5
_______________________
Column type frequency:
character 3
numeric 2
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
sexe_chef 0 1 1 1 0 2 0
structure 0 1 1 1 0 5 0
richesse 0 1 1 1 0 5 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
id_menage 0 1 907.5 523.80 1 454.25 907.5 1360.75 1814 <U+2587><U+2587><U+2587><U+2587><U+2587>
taille 0 1 7.5 4.42 1 4.00 6.0 9.00 31 <U+2587><U+2585><U+2581><U+2581><U+2581>

create_report (DataExplorer)

L’extension DataExplorer fournit des outils d’exploration graphique d’un fichier de données. En premier lieu, sa fonction create_report génère un rapport automatique à partir d’un tableau de données.

library(DataExplorer)
create_report(hdv2003)

Le résultat de ce rapport est visible sur http://larmarange.github.io/analyse-R/data/hdv2003_DataExplorer_report.html.

L’extension fournit également différentes fonctions graphiques, présentées en détail dans la vignette inclue dans l’extension et visible sur https://cran.r-project.org/web/packages/DataExplorer/vignettes/dataexplorer-intro.html.

makeCodebook (dataMaid)

L’extension dataMaid propose une fonction makeCodebook permettant de générer une présentation de l’ensemble des variables d’un tableau de données, au format PDF, Word ou HTML.

library(dataMaid)
makeCodebook(hdv2003)

Vous pouvez cliquez sur ce lien pour voir le PDF produit par dataMaid.

Recodage de variables

La version originale de ce chapitre a été écrite par Julien Barnier dans le cadre du support de cours Introduction à R.

Le recodage de variables est une opération extrêmement fréquente lors du traitement d’enquête. Celui-ci utilise soit l’une des formes d’indexation décrites précédemment, soit des fonctions ad hoc de R.

On passe ici en revue différents types de recodage parmi les plus courants. Les exemples s’appuient, comme précédemment, sur l’extrait de l’enquête Histoire de vie :

library(questionr)
data(hdv2003)
d <- hdv2003

Renommer des variables

Une opération courante lorsqu’on a importé des variables depuis une source de données externe consiste à renommer les variables importées. Sous R les noms de variables doivent être à la fois courts et explicites.

Les noms de variables peuvent contenir des lettres, des chiffres (mais ils ne peuvent pas commencer par un chiffre), les symboles . et _ et doivent commencer par une lettre. R fait la différence entre les majuscules et les minuscules, ce qui signifie que x et X sont deux noms de variable différents. On évitera également d’utiliser des caractères accentués dans les noms de variable. Comme les espaces ne sont pas autorisés, on pourra les remplacer par un point ou un tiret bas.

On peut lister les noms des variables d’un tableau de données (data.frame) à l’aide de la fonction names :

names(d)
 [1] "id"            "age"           "sexe"         
 [4] "nivetud"       "poids"         "occup"        
 [7] "qualif"        "freres.soeurs" "clso"         
[10] "relig"         "trav.imp"      "trav.satisf"  
[13] "hard.rock"     "lecture.bd"    "peche.chasse" 
[16] "cuisine"       "bricol"        "cinema"       
[19] "sport"         "heures.tv"    

Cette fonction peut également être utilisée pour renommer l’ensemble des variables. Si par exemple on souhaitait passer les noms de toutes les variables en majuscules, on pourrait faire :

d.maj <- d
names(d.maj) <- c(
  "ID", "AGE", "SEXE", "NIVETUD", "POIDS", "OCCUP", "QUALIF",
  "FRERES.SOEURS", "CLSO", "RELIG", "TRAV.IMP", "TRAV.SATISF", "HARD.ROCK",
  "LECTURE.BD", "PECHE.CHASSE", "CUISINE", "BRICOL", "CINEMA", "SPORT", "HEURES.TV"
)
summary(d.maj$SEXE)
Homme Femme 
  899  1101 

Ce type de renommage peut être utile lorsqu’on souhaite passer en revue tous les noms de variables d’un fichier importé pour les corriger le cas échéant. Pour faciliter un peu ce travail pas forcément passionnant, on peut utiliser la fonction dput :

dput(names(d))
c("id", "age", "sexe", "nivetud", "poids", "occup", "qualif", 
"freres.soeurs", "clso", "relig", "trav.imp", "trav.satisf", 
"hard.rock", "lecture.bd", "peche.chasse", "cuisine", "bricol", 
"cinema", "sport", "heures.tv")

On obtient en résultat la liste des variables sous forme de vecteur déclaré. On n’a plus alors qu’à copier/coller cette chaîne, rajouter names(d) <- devant et modifier un à un les noms des variables.

Si on souhaite seulement modifier le nom d’une variable, on peut utiliser la fonction rename.variable de l’extension questionr. Celle-ci prend en argument le tableau de données, le nom actuel de la variable et le nouveau nom. Par exemple, si on veut renommer la variable bricol du tableau de données d en bricolage :

d <- rename.variable(d, "bricol", "bricolage")
table(d$bricolage)

 Non  Oui 
1147  853 

Convertir une variable

Il peut arriver qu’on veuille transformer une variable d’un type dans un autre.

Variable numérique ou textuelle en facteur

Par exemple, on peut considérer que la variable numérique freres.soeurs est une « fausse » variable numérique et qu’une représentation sous forme de facteur serait plus adéquate. Dans ce cas il suffit de faire appel à la fonction factor :

d$fs.fac <- factor(d$freres.soeurs)
levels(d$fs.fac)
 [1] "0"  "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10"
[12] "11" "12" "13" "14" "15" "16" "18" "22"

La conversion d’une variable caractères en facteur se fait de la même manière.

La conversion d’un facteur ou d’une variable numérique en variable caractères peut se faire à l’aide de la fonction as.character :

d$fs.char <- as.character(d$freres.soeurs)
d$qualif.char <- as.character(d$qualif)

Conversion d’un facteur

La conversion d’un facteur en caractères est fréquemment utilisé lors des recodages du fait qu’il est impossible d’ajouter de nouvelles modalités à un facteur de cette manière. Par exemple, la première des commandes suivantes génère un message d’avertissement, tandis que les deux autres fonctionnent :

d.temp <- d
d.temp$qualif[d.temp$qualif == "Ouvrier specialise"] <- "Ouvrier"
Warning in `[<-.factor`(`*tmp*`, d.temp$qualif == "Ouvrier
specialise", : invalid factor level, NA generated
d$qualif.char <- as.character(d$qualif)
d$qualif.char[d$qualif.char == "Ouvrier specialise"] <- "Ouvrier"

Dans le premier cas, le message d’avertissement indique que toutes les modalités « Ouvrier specialise » de notre variable qualif ont été remplacées par des valeurs manquantes NA.

Enfin, une variable de type caractères dont les valeurs seraient des nombres peut être convertie en variable numérique avec la fonction as.numeric.

v <- c("1", "3.1415", "4", "5.6", "1", "4")
v
[1] "1"      "3.1415" "4"      "5.6"    "1"      "4"     
as.numeric(v)
[1] 1.0000 3.1415 4.0000 5.6000 1.0000 4.0000

Lorsque l’on convertit un facteur avec as.numeric, on obtient le numéro de chaque facteur (première modalité, seconde modalité, etc.). Si la valeur numérique qui nous intéresse est en fait contenu dans le nom des modalités, il faut convertir au préalable notre facteur en variable textuelle.

vf <- factor(v)
vf
[1] 1      3.1415 4      5.6    1      4     
Levels: 1 3.1415 4 5.6
as.numeric(vf)
[1] 1 2 3 4 1 3
as.numeric(as.character(vf))
[1] 1.0000 3.1415 4.0000 5.6000 1.0000 4.0000

ATTENTION : la valeur numérique associée à chaque étiquette d’un facteur change lorsque l’on modifie l’ordre des étiquettes d’un facteur. Dès lors, il est fortement déconseillé de convertir un facteur en variable numérique.

Conversion d’un vecteur labellisé

Nous avons abordé dans un chapitre précédent la gestion de données labellisées à l’aide de l’extension labelled. Les vecteurs labellisés sont beaucoup plus souples que les facteurs lors de la préparation des données, puisque la liste des modalités autorisées n’est pas fixée à l’avance. De plus, cela permet également de documenter au-fur-et-à-mesure les nouvelles variables que l’on créé.

Nous verrons dans les chapitres d’analyse, notamment quand il s’agit de calculer des modèles, qu’il est nécessaire de coder les variables catégorielles sous forme de facteurs. Et il est préférable pour les variables continues de leur retirer la classe haven_labelled.

Quand convertir les vecteurs labellisés ?

La classe haven_labelled permets d’ajouter des métadonnées aux variables sous la forme d’étiquettes de valeurs. Lorsque les données sont importées depuis SAS, SPSS ou Stata, cela permet notamment de conserver le codage original du fichier importé.

Mais il faut noter que ces étiquettes de valeur n’indique pas pour autant de manière systématique le type de variable (catégorielle ou continue). Les vecteurs labellisés n’ont donc pas vocation à être utilisés pour l’analyse, notamment le calcul de modèles statistiques. Ils doivent être convertis en facteurs (pour les variables catégorielles) ou en vecteurs numériques (pour les variables continues).

La question qui peut se poser est donc de choisirà quel moment cette conversion doit avoir lieu dans un processus d’analyse. On peut considérer deux approches principales.

Deux approches possibles

Dans l’approche A, les vecteurs labellisés sont convertis juste après l’import des données, en utilisant les fonctions unlabelled, to_factor ou unclass qui sont présentées ci-après. Dès lors, toute la partie de nettoyage et de recodage des données se fera en utilisant les fonctions classiques de R.

Dans l’approche B, les vecteurs labellisés sont conservés pour l’étape de nettoyage et de recodage des données. Dans ce cas là, on pourra avoir recours aux fonctions de l’extension labelled qui facilitent la gestion des données labellisées. Cette approche est particulièrement intéressante quand (i) on veut pouvoir se référer au dictionnaire de codification fourni avec les données sources et donc on veut conserver le codage original et/ou (ii) quand les données devront faire l’objet d’un réexport après transformation. Par contre, comme dans l’approche A, il faudra prévoir une conversion des variables labellisées au moment de l’analyse.

Convertir un vecteur labellisé en facteur

Il est très facile de convertir un vecteur labellisé en facteur à l’aide la fonction to_factor de l’extension labelled1.

library(labelled)
v <- labelled(c(1, 2, 9, 3, 3, 2, NA), c(oui = 1, "peut-être" = 2, non = 3, "ne sait pas" = 9))
v
<labelled<double>[7]>
[1]  1  2  9  3  3  2 NA

Labels:
 value       label
     1         oui
     2   peut-être
     3         non
     9 ne sait pas
to_factor(v)
[1] oui         peut-être   ne sait pas non        
[5] non         peut-être   <NA>       
Levels: oui peut-être non ne sait pas

Il possible d’indiquer si l’on souhaite, comme étiquettes du facteur, utiliser les étiquettes de valeur (par défaut), les valeurs elles-mêmes, ou bien les étiquettes de valeurs préfixées par la valeur d’origine indiquée entre crochets.

to_factor(v, "l")
[1] oui         peut-être   ne sait pas non        
[5] non         peut-être   <NA>       
Levels: oui peut-être non ne sait pas
to_factor(v, "v")
[1] 1    2    9    3    3    2    <NA>
Levels: 1 2 3 9
to_factor(v, "p")
[1] [1] oui         [2] peut-être   [9] ne sait pas
[4] [3] non         [3] non         [2] peut-être  
[7] <NA>           
4 Levels: [1] oui [2] peut-être ... [9] ne sait pas

Par défaut, les étiquettes du facteur seront triés selon l’ordre des étiquettes de valeur. Mais cela peut être modifié avec l’argument sort_levels si l’on préfère trier selon les valeurs ou selon l’ordre alphabétique des étiquettes.

to_factor(v, sort_levels = "v")
[1] oui         peut-être   ne sait pas non        
[5] non         peut-être   <NA>       
Levels: oui peut-être non ne sait pas
to_factor(v, sort_levels = "l")
[1] oui         peut-être   ne sait pas non        
[5] non         peut-être   <NA>       
Levels: ne sait pas non oui peut-être

D’autres options sont disponibles. On se réferra à la documentation complète de la fonction.

Convertir un vecteur labellisé en numérique ou en texte

Pour rappel, il existe deux types de vecteurs labellisés : des vecteurs numériques labellisés (x dans l’exemple ci-dessous) et des vecteurs textuels labellisés (x dans l’exemple ci-dessous).

x <- labelled(c(1, 2, 9, 3, 3, 2, NA), c(oui = 1, "peut-être" = 2, non = 3, "ne sait pas" = 9))
y <- labelled(c("f", "f", "h", "f"), c(femme = "f", homme = "h"))
x
<labelled<double>[7]>
[1]  1  2  9  3  3  2 NA

Labels:
 value       label
     1         oui
     2   peut-être
     3         non
     9 ne sait pas
y
<labelled<character>[4]>
[1] f f h f

Labels:
 value label
     f femme
     h homme

Pour leur retirer leur caractère labellisé et revenir à leur classe d’origine, on peut utiliser la fonction unclass.

unclass(x)
[1]  1  2  9  3  3  2 NA
attr(,"labels")
        oui   peut-être         non ne sait pas 
          1           2           3           9 
unclass(y)
[1] "f" "f" "h" "f"
attr(,"labels")
femme homme 
  "f"   "h" 

À noter que dans ce cas-là, les étiquettes sont conservées comme attributs du vecteur.

Une alternative est d’utiliser remove_labels qui supprimera toutes les étiquettes, y compris les étiquettes de variable. Pour conserver les étiquettes de variables et ne supprimer que les étiquettes de valeurs, on indiquera keep_var_label = TRUE.

var_label(x) <- "Etiquette de variable"
remove_labels(x)
[1]  1  2  9  3  3  2 NA
remove_labels(x, keep_var_label = TRUE)
[1]  1  2  9  3  3  2 NA
attr(,"label")
[1] "Etiquette de variable"
remove_labels(y)
[1] "f" "f" "h" "f"

Dans le cas d’un vecteur numérique labellisé que l’on souhaiterait convertir en variable textuelle, on pourra utiliser to_character à la place de to_factor qui comme sa soeur utilisera les étiquettes de valeurs.

to_character(x)
[1] "oui"         "peut-être"   "ne sait pas" "non"        
[5] "non"         "peut-être"   NA           
attr(,"label")
[1] "Etiquette de variable"

Conversion conditionnelle en facteurs

Il n’est pas toujours possible de déterminer la nature d’une variable (continue ou catégorielle) juste à partir de la présence ou l’absence d’étiquettes de valeur. En effet, on peut utiliser des étiquettes de valeur dans le cadre d’une variable continue pour indiquer certaines valeurs spécifiques.

Une bonne pratique est de vérifier chaque variable inclue dans une analyse, une à une.

Cependant, une règle qui fonctionne dans 90% des cas est de convertir un vecteur labellisé en facteur seulement si toutes les valeurs observées dans le vecteur disposent d’une étiquette de valeur correspondante. C’est ce que propose la fonction unlabelled qui peut même être appliqué à tout un tableau de données. Par défaut, elle fonctionne ainsi :

  1. les variables non labellisées restent inchangées (variables f et g dans l’exemple ci-dessous);
  2. si toutes les valeurs observées d’une variable labellisées, elles sont converties en facteurs (variables b et c);
  3. sinon, on leur applique unclass (variables a, d et e).
df <- data.frame(
  a = labelled(c(1, 1, 2, 3), labels = c(No = 1, Yes = 2)),
  b = labelled(c(1, 1, 2, 3), labels = c(No = 1, Yes = 2, DK = 3)),
  c = labelled(c(1, 1, 2, 2), labels = c(No = 1, Yes = 2, DK = 3)),
  d = labelled(c("a", "a", "b", "c"), labels = c(No = "a", Yes = "b")),
  e = labelled_spss(
    c(1, 9, 1, 2),
    labels = c(No = 1, Yes = 2),
    na_values = 9
  ),
  f = 1:4,
  g = as.Date(c("2020-01-01", "2020-02-01", "2020-03-01", "2020-04-01"))
)
dplyr::glimpse(df)
Rows: 4
Columns: 7
$ a <dbl+lbl> 1, 1, 2, 3
$ b <dbl+lbl> 1, 1, 2, 3
$ c <dbl+lbl> 1, 1, 2, 2
$ d <chr+lbl> "a", "a", "b", "c"
$ e <dbl+lbl> 1, 9, 1, 2
$ f <int> 1, 2, 3, 4
$ g <date> 2020-01-01, 2020-02-01, 2020-03-01, 2020-04-01
dplyr::glimpse(unlabelled(df))
Rows: 4
Columns: 7
$ a <dbl> 1, 1, 2, 3
$ b <fct> No, No, Yes, DK
$ c <fct> No, No, Yes, Yes
$ d <chr> "a", "a", "b", "c"
$ e <fct> No, NA, No, Yes
$ f <int> 1, 2, 3, 4
$ g <date> 2020-01-01, 2020-02-01, 2020-03-01, 2020-04-01

On peut indiquer certaines options, par exemple drop_unused_labels = TRUE pour supprimer des facteurs créés les niveaux non observées dans les données (voir la variable c) ou user_na_to_na = TRUE pour convertir les valeurs manquantes de type SPSS en NA (voir la variable e, notez qu’ici, du fait de cette conversion, toutes les valeurs ont une étiquette et la variable est alors convertie en facteur.)

dplyr::glimpse(unlabelled(df, levels = "prefixed"))
Rows: 4
Columns: 7
$ a <dbl> 1, 1, 2, 3
$ b <fct> [1] No, [1] No, [2] Yes, [3] DK
$ c <fct> [1] No, [1] No, [2] Yes, [2] Yes
$ d <chr> "a", "a", "b", "c"
$ e <fct> [1] No, NA, [1] No, [2] Yes
$ f <int> 1, 2, 3, 4
$ g <date> 2020-01-01, 2020-02-01, 2020-03-01, 2020-04-01
dplyr::glimpse(unlabelled(df, user_na_to_na = TRUE))
Rows: 4
Columns: 7
$ a <dbl> 1, 1, 2, 3
$ b <fct> No, No, Yes, DK
$ c <fct> No, No, Yes, Yes
$ d <chr> "a", "a", "b", "c"
$ e <fct> No, NA, No, Yes
$ f <int> 1, 2, 3, 4
$ g <date> 2020-01-01, 2020-02-01, 2020-03-01, 2020-04-01
dplyr::glimpse(unlabelled(df, drop_unused_labels = TRUE))
Rows: 4
Columns: 7
$ a <dbl> 1, 1, 2, 3
$ b <fct> No, No, Yes, DK
$ c <fct> No, No, Yes, Yes
$ d <chr> "a", "a", "b", "c"
$ e <fct> No, NA, No, Yes
$ f <int> 1, 2, 3, 4
$ g <date> 2020-01-01, 2020-02-01, 2020-03-01, 2020-04-01

Découper une variable numérique en classes

Le premier type de recodage consiste à découper une variable de type numérique en un certain nombre de classes. On utilise pour cela la fonction cut.

Celle-ci prend, outre la variable à découper, un certain nombre d’arguments :

  • breaks indique soit le nombre de classes souhaité, soit, si on lui fournit un vecteur, les limites des classes ;
  • labels permet de modifier les noms de modalités attribués aux classes ;
  • include.lowest et right influent sur la manière dont les valeurs situées à la frontière des classes seront inclues ou exclues ;
  • dig.lab indique le nombre de chiffres après la virgule à conserver dans les noms de modalités.

Prenons tout de suite un exemple et tentons de découper notre variable age en cinq classes et de placer le résultat dans une nouvelle variable nommée age5cl :

d$age5cl <- cut(d$age, 5)
table(d$age5cl)

(17.9,33.8] (33.8,49.6] (49.6,65.4] (65.4,81.2] (81.2,97.1] 
        454         628         556         319          43 

Par défaut R nous a bien créé cinq classes d’amplitudes égales. La première classe va de 16,9 à 32,2 ans (en fait de 17 à 32), etc.

Les frontières de classe seraient plus présentables si elles utilisaient des nombres ronds. On va donc spécifier manuellement le découpage souhaité, par tranches de 20 ans :

d$age20 <- cut(d$age, c(0, 20, 40, 60, 80, 100))
table(d$age20)

  (0,20]  (20,40]  (40,60]  (60,80] (80,100] 
      72      660      780      436       52 

On aurait pu tenir compte des âges extrêmes pour la première et la dernière valeur :

range(d$age)
[1] 18 97
d$age20 <- cut(d$age, c(18, 20, 40, 60, 80, 97))
table(d$age20)

(18,20] (20,40] (40,60] (60,80] (80,97] 
     55     660     780     436      52 

Les symboles dans les noms attribués aux classes ont leur importance : ( signifie que la frontière de la classe est exclue, tandis que [ signifie qu’elle est incluse. Ainsi, (20,40] signifie « strictement supérieur à 20 et inférieur ou égal à 40 ».

On remarque que du coup, dans notre exemple précédent, la valeur minimale, 18, est exclue de notre première classe, et qu’une observation est donc absente de ce découpage. Pour résoudre ce problème on peut soit faire commencer la première classe à 17, soit utiliser l’option include.lowest=TRUE :

d$age20 <- cut(d$age, c(17, 20, 40, 60, 80, 97))
table(d$age20)

(17,20] (20,40] (40,60] (60,80] (80,97] 
     72     660     780     436      52 
d$age20 <- cut(d$age, c(18, 20, 40, 60, 80, 97), include.lowest = TRUE)
table(d$age20)

[18,20] (20,40] (40,60] (60,80] (80,97] 
     72     660     780     436      52 

On peut également modifier le sens des intervalles avec l’option right=FALSE, et indiquer manuellement les noms des modalités avec labels :

d$age20 <- cut(d$age, c(18, 20, 40, 60, 80, 97), right = FALSE, include.lowest = TRUE)
table(d$age20)

[18,20) [20,40) [40,60) [60,80) [80,97] 
     48     643     793     454      62 
d$age20 <- cut(d$age, c(18, 20, 40, 60, 80, 97), include.lowest = TRUE, labels = c("<20ans", "21-40 ans", "41-60ans", "61-80ans", ">80ans"))
table(d$age20)

   <20ans 21-40 ans  41-60ans  61-80ans    >80ans 
       72       660       780       436        52 

L’extension questionr propose une interface interactive à la fonction cut, nommée icut. Elle s’utilise de la manière suivante :

icut(d, age)

RStudio devrait ouvrir une fenêtre semblable à l’image ci-dessous.

Capture d’écran d’icut

Vous pouvez alors indiquer les limites de vos classes ainsi que quelques options complémentaires. Ces limites sont représentées graphiquement sur l’histogramme de la variable d’origine.

L’onglet Vérification affiche un tri à plat et un graphique en barres de la nouvelle variable. Une fois le résultat satisfaisant, vous pouvez récupérer le code généré pour l’inclure dans votre script.

L’extension questionr propose aussi une fonction quant.cut permettant de découper une variable numérique en un nombre de classes donné ayant des efffectifs semblables. Il suffit de lui passer le nombre de classes en argument :

d$age6cl <- quant.cut(d$age, 6)
table(d$age6cl)

    [18,30)     [30,39)     [39,48) [48,55.667) [55.667,66) 
        302         337         350         344         305 
    [66,97] 
        362 

quant.cut admet les mêmes autres options que cut (include.lowest, right, labels… ).

Regrouper les modalités d’une variable

Pour regrouper les modalités d’une variable qualitative (d’un facteur le plus souvent), on peut utiliser directement l’indexation.

Ainsi, si on veut recoder la variable qualif dans une variable qualif.reg plus « compacte », on peut utiliser :

table(d$qualif)

      Ouvrier specialise         Ouvrier qualifie 
                     203                      292 
              Technicien Profession intermediaire 
                      86                      160 
                   Cadre                  Employe 
                     260                      594 
                   Autre 
                      58 
d$qualif.reg[d$qualif == "Ouvrier specialise"] <- "Ouvrier"
d$qualif.reg[d$qualif == "Ouvrier qualifie"] <- "Ouvrier"
d$qualif.reg[d$qualif == "Employe"] <- "Employe"
d$qualif.reg[d$qualif == "Profession intermediaire"] <- "Intermediaire"
d$qualif.reg[d$qualif == "Technicien"] <- "Intermediaire"
d$qualif.reg[d$qualif == "Cadre"] <- "Cadre"
d$qualif.reg[d$qualif == "Autre"] <- "Autre"
table(d$qualif.reg)

        Autre         Cadre       Employe Intermediaire 
           58           260           594           246 
      Ouvrier 
          495 

On aurait pu représenter ce recodage de manière plus compacte, notamment en commençant par copier le contenu de qualif dans qualif.reg, ce qui permet de ne pas s’occuper de ce qui ne change pas.

Il est cependant nécessaire de ne pas copier qualif sous forme de facteur, sinon on ne pourrait ajouter de nouvelles modalités. On copie donc la version caractères de qualif grâce à la fonction as.character :

d$qualif.reg <- as.character(d$qualif)
d$qualif.reg[d$qualif == "Ouvrier specialise"] <- "Ouvrier"
d$qualif.reg[d$qualif == "Ouvrier qualifie"] <- "Ouvrier"
d$qualif.reg[d$qualif == "Profession intermediaire"] <- "Intermediaire"
d$qualif.reg[d$qualif == "Technicien"] <- "Intermediaire"
table(d$qualif.reg)

        Autre         Cadre       Employe Intermediaire 
           58           260           594           246 
      Ouvrier 
          495 

On peut faire une version encore plus compacte en utilisant l’opérateur logique ou (|) :

d$qualif.reg <- as.character(d$qualif)
d$qualif.reg[d$qualif == "Ouvrier specialise" | d$qualif == "Ouvrier qualifie"] <- "Ouvrier"
d$qualif.reg[d$qualif == "Profession intermediaire" | d$qualif == "Technicien"] <- "Intermediaire"
table(d$qualif.reg)

        Autre         Cadre       Employe Intermediaire 
           58           260           594           246 
      Ouvrier 
          495 

Enfin, pour terminer ce petit tour d’horizon, on peut également remplacer l’opérateur | par %in%, qui peut parfois être plus lisible :

d$qualif.reg <- as.character(d$qualif)
d$qualif.reg[d$qualif %in% c("Ouvrier specialise", "Ouvrier qualifie")] <- "Ouvrier"
d$qualif.reg[d$qualif %in% c("Profession intermediaire", "Technicien")] <- "Intermediaire"
table(d$qualif.reg)

        Autre         Cadre       Employe Intermediaire 
           58           260           594           246 
      Ouvrier 
          495 

Dans tous les cas le résultat obtenu est une variable de type caractère. On pourra la convertir en facteur par un simple :

d$qualif.reg <- factor(d$qualif.reg)

Si on souhaite recoder les valeurs manquantes, il suffit de faire appel à la fonction is.na :

table(d$trav.satisf)

  Satisfaction Insatisfaction      Equilibre 
           480            117            451 
d$trav.satisf.reg <- as.character(d$trav.satisf)
d$trav.satisf.reg[is.na(d$trav.satisf)] <- "Manquant"
table(d$trav.satisf.reg)

     Equilibre Insatisfaction       Manquant   Satisfaction 
           451            117            952            480 

questionr propose une interface interactive pour le recodage d’une variable qualitative (renommage et regroupement de modalités). Cette fonction, nommée irec, s’utilise de la manière suivante :

irec(d, qualif)

RStudio va alors ouvrir une fenêtre semblable à l’image ci-dessous :

Capture de irec

Vous pouvez alors sélectionner différentes options, et pour chaque ancienne modalité, indiquer la nouvelle valeur correspondante. Pour regrouper des modalités, il suffit de leur assigner des nouvelles valeurs identiques. Dans tous les cas n’hésitez pas à expérimenter, l’interface se contente de générer du code R à copier/coller dans votre script mais ne l’exécute pas, et ne modifie donc jamais vos données !

L’onglet Vérification affiche un tri croisé de l’ancienne et de la nouvelle variable pour vérifier que le recodage est correct. Une fois le résultat satisfaisant, vous pouvez récupérer le code généré dans l’onglet Code pour l’inclure dans votre script.

Les exemples précédents montrent bien qu’il est parfois malaisé d’utiliser des facteurs lorsque l’on recode des variables. Les vecteurs labellisés sont, quant à eux, plus souples. Attention : avec des vecteurs labellisés, on utilisera les valeurs sous-jacentes et non les étiquettes pour écrire des conditions.

data(fecondite)
library(labelled)
describe(femmes$educ)
[2000 obs.] Niveau d'éducation
labelled double: 0 0 0 0 1 0 0 0 0 0 ...
min: 0 - max: 3 - NAs: 0 (0%) - 4 unique values
4 value labels: [0] aucun [1] primaire [2] secondaire [3] supérieur

                  n     %
[0] aucun      1138  56.9
[1] primaire    460  23.0
[2] secondaire  348  17.4
[3] supérieur    54   2.7
Total          2000 100.0
femmes$educ2 <- 0
femmes$educ2[femmes$educ >= 2] <- 1
var_label(femmes$educ2) <- "A atteint un niveau secondaire ou supérieur ?"
val_labels(femmes$educ2) <- c(non = 0, oui = 1)
describe(femmes$educ2)
[2000 obs.] A atteint un niveau secondaire ou supérieur ?
labelled double: 0 0 0 0 0 0 0 0 0 0 ...
min: 0 - max: 1 - NAs: 0 (0%) - 2 unique values
2 value labels: [0] non [1] oui

           n     %
[0] non 1598  79.9
[1] oui  402  20.1
Total   2000 100.0

Il est aussi prossible d’avoir recours à la méthode recode de dplyr pour les vecteurs labelisés à condition que l’extension labelled soit chargée en mémoire. Il faut indiquer les recodifications sous la forme ancienne_valeur = nouvelle_valeur. Par défaut, les étiquettes de valeurs ne sont pas modifiées, sauf si l’on indique .combine_value_labels = FALSE (voir l’aide de recode.haven_labelled).

library(dplyr)

Attaching package: 'dplyr'
The following objects are masked from 'package:stats':

    filter, lag
The following objects are masked from 'package:base':

    intersect, setdiff, setequal, union
library(labelled)
freq(femmes$educ)
femmes <- femmes %>% mutate(educ3 = recode(educ, `3` = 2))
freq(femmes$educ3)
femmes <- femmes %>% mutate(educ4 = recode(educ, `3` = 2, .combine_value_labels = TRUE))
freq(femmes$educ4)

Variables calculées

La création d’une variable numérique à partir de calculs sur une ou plusieurs autres variables numériques se fait très simplement.

Supposons que l’on souhaite calculer une variable indiquant l’écart entre le nombre d’heures passées à regarder la télévision et la moyenne globale de cette variable. On pourrait alors faire :

range(d$heures.tv, na.rm = TRUE)
[1]  0 12
mean(d$heures.tv, na.rm = TRUE)
[1] 2.246566
d$ecart.heures.tv <- d$heures.tv - mean(d$heures.tv, na.rm = TRUE)
range(d$ecart.heures.tv, na.rm = TRUE)
[1] -2.246566  9.753434
mean(d$ecart.heures.tv, na.rm = TRUE)
[1] 4.714578e-17

Autre exemple tiré du jeu de données rp99 : si on souhaite calculer le pourcentage d’actifs dans chaque commune, on peut diviser la population active pop.act par la population totale pop.tot.

data("rp99")
rp99$part.actifs <- rp99$pop.act / rp99$pop.tot * 100

Combiner plusieurs variables

La combinaison de plusieurs variables se fait à l’aide des techniques d’indexation déjà décrites précédemment. Le plus compliqué est d’arriver à formuler des conditions parfois complexes de manière rigoureuse.

On peut ainsi vouloir combiner plusieurs variables qualitatives en une seule :

d$act.manuelles <- NA
d$act.manuelles[d$cuisine == "Oui" & d$bricol == "Oui"] <- "Cuisine et Bricolage"
d$act.manuelles[d$cuisine == "Oui" & d$bricol == "Non"] <- "Cuisine seulement"
d$act.manuelles[d$cuisine == "Non" & d$bricol == "Oui"] <- "Bricolage seulement"
d$act.manuelles[d$cuisine == "Non" & d$bricol == "Non"] <- "Ni cuisine ni bricolage"
table(d$act.manuelles)

    Bricolage seulement    Cuisine et Bricolage 
                    437                     416 
      Cuisine seulement Ni cuisine ni bricolage 
                    465                     682 

On peut également combiner variables qualitatives et variables quantitatives :

d$age.sexe <- NA
d$age.sexe[d$sexe == "Homme" & d$age < 40] <- "Homme moins de 40 ans"
d$age.sexe[d$sexe == "Homme" & d$age >= 40] <- "Homme plus de 40 ans"
d$age.sexe[d$sexe == "Femme" & d$age < 40] <- "Femme moins de 40 ans"
d$age.sexe[d$sexe == "Femme" & d$age >= 40] <- "Femme plus de 40 ans"
table(d$age.sexe)

Femme moins de 40 ans  Femme plus de 40 ans 
                  376                   725 
Homme moins de 40 ans  Homme plus de 40 ans 
                  315                   584 

Les combinaisons de variables un peu complexes nécessitent parfois un petit travail de réflexion. En particulier, l’ordre des commandes de recodage a parfois une influence dans le résultat final.

Pour combiner rapidement plusieurs variables entre elles, on peut aussi avoir recours à la fonction interaction qui créra un facteur avec un niveau pour chaque combinaison de modalités des variables sources.

d$age20.sexe <- interaction(d$sexe, d$age20)
table(d$age20.sexe)

   Homme.<20ans    Femme.<20ans Homme.21-40 ans 
             34              38             291 
Femme.21-40 ans  Homme.41-60ans  Femme.41-60ans 
            369             352             428 
 Homme.61-80ans  Femme.61-80ans    Homme.>80ans 
            205             231              17 
   Femme.>80ans 
             35 

Variables scores

Une variable score est une variable calculée en additionnant des poids accordés aux modalités d’une série de variables qualitatives.

Pour prendre un exemple tout à fait arbitraire, imaginons que nous souhaitons calculer un score d’activités extérieures. Dans ce score on considère que le fait d’aller au cinéma « pèse » 10, celui de pêcher ou chasser vaut 30 et celui de faire du sport vaut 20. On pourrait alors calculer notre score de la manière suivante :

d$score.ext <- 0
d$score.ext[d$cinema == "Oui"] <- d$score.ext[d$cinema == "Oui"] + 10
d$score.ext[d$peche.chasse == "Oui"] <- d$score.ext[d$peche.chasse == "Oui"] + 30
d$score.ext[d$sport == "Oui"] <- d$score.ext[d$sport == "Oui"] + 20
table(d$score.ext)

  0  10  20  30  40  50  60 
800 342 229 509  31  41  48 

Cette notation étant un peu lourde, on peut l’alléger un peu en utilisant la fonction ifelse. Celle-ci prend en argument une condition et deux valeurs. Si la condition est vraie elle retourne la première valeur, sinon elle retourne la seconde.

d$score.ext <- 0
d$score.ext <- ifelse(d$cinema == "Oui", 10, 0) + ifelse(d$peche.chasse == "Oui", 30, 0) + ifelse(d$sport == "Oui", 20, 0)
table(d$score.ext)

  0  10  20  30  40  50  60 
800 342 229 509  31  41  48 

Vérification des recodages

Il est très important de vérifier, notamment après les recodages les plus complexes, qu’on a bien obtenu le résultat escompté. Les deux points les plus sensibles étant les valeurs manquantes et les erreurs dans les conditions.

Pour vérifier tout cela, le plus simple est sans doute de faire des tableaux croisés entre la variable recodée et celles ayant servi au recodage, à l’aide des fonctions table ou xtabs, et de vérifier le nombre de valeurs manquantes dans la variable recodée avec summary, freq ou table.

Par exemple :

d$act.manuelles <- NA
d$act.manuelles[d$cuisine == "Oui" & d$bricol == "Oui"] <- "Cuisine et Bricolage"
d$act.manuelles[d$cuisine == "Oui" & d$bricol == "Non"] <- "Cuisine seulement"
d$act.manuelles[d$cuisine == "Non" & d$bricol == "Oui"] <- "Bricolage seulement"
d$act.manuelles[d$cuisine == "Non" & d$bricol == "Non"] <- "Ni cuisine ni bricolage"
table(d$act.manuelles, d$cuisine)
                         
                          Non Oui
  Bricolage seulement     437   0
  Cuisine et Bricolage      0 416
  Cuisine seulement         0 465
  Ni cuisine ni bricolage 682   0
table(d$act.manuelles, d$bricol)
                         
                          Non Oui
  Bricolage seulement       0 437
  Cuisine et Bricolage      0 416
  Cuisine seulement       465   0
  Ni cuisine ni bricolage 682   0

Facteurs et forcats

forcats est une extension facilitant la manipulation des variables qualitatives, qu’elles soient sous forme de vecteurs character ou de facteurs. Elle fait partie du tidyverse, et est donc automatiquement chargée par :

library(tidyverse)
-- Attaching packages ------------------- tidyverse 1.3.0 --
v ggplot2 3.3.2     v purrr   0.3.4
v tibble  3.0.4     v stringr 1.4.0
v tidyr   1.1.2     v forcats 0.5.0
v readr   1.4.0     
-- Conflicts ---------------------- tidyverse_conflicts() --
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()

Modifier les modalités d’une variable qualitative

Une opération courante consiste à modifier les valeurs d’une variable qualitative, que ce soit pour avoir des intitulés plus courts ou plus clairs ou pour regrouper des modalités entre elles.

Il existe plusieurs possibilités pour effectuer ce type de recodage, mais ici on va utiliser la fonction fct_recode de l’extension forcats. Celle-ci prend en argument une liste de recodages sous la forme "Nouvelle valeur" = "Ancienne valeur".

Un exemple :

f <- c("Pomme", "Poire", "Pomme", "Cerise")
f <- fct_recode(f,
  "Fraise" = "Pomme",
  "Ananas" = "Poire"
)
f
[1] Fraise Ananas Fraise Cerise
Levels: Cerise Ananas Fraise

Autre exemple sur une “vraie” variable :

freq(hdv2003$qualif)
hdv2003$qualif5 <- fct_recode(hdv2003$qualif,
  "Ouvrier" = "Ouvrier specialise",
  "Ouvrier" = "Ouvrier qualifie",
  "Interm" = "Technicien",
  "Interm" = "Profession intermediaire"
)

freq(hdv2003$qualif5)

Attention, les anciennes valeurs saisies doivent être exactement égales aux valeurs des modalités de la variable recodée : toute différence d’accent ou d’espace fera que ce recodage ne sera pas pris en compte. Dans ce cas, forcats affiche un avertissement nous indiquant qu’une valeur saisie n’a pas été trouvée dans les modalités de la variable :

hdv2003$qualif_test <- fct_recode(hdv2003$qualif,
  "Ouvrier" = "Ouvrier spécialisé",
  "Ouvrier" = "Ouvrier qualifié"
)
Warning: Unknown levels in `f`: Ouvrier spécialisé, Ouvrier
qualifié

Si on souhaite recoder une modalité de la variable en NA, il faut (contre intuitivement) lui assigner la valeur NULL :

hdv2003$qualif_rec <- fct_recode(hdv2003$qualif, NULL = "Autre")

freq(hdv2003$qualif_rec)

À l’inverse, si on souhaite recoder les NA d’une variable, on utilisera la fonction fct_explicit_na, qui convertit toutes les valeurs manquantes (NA) d’un facteur en une modalité spécifique :

hdv2003$qualif_rec <- fct_explicit_na(hdv2003$qualif, na_level = "(Manquant)")

freq(hdv2003$qualif_rec)

D’autres fonctions sont proposées par forcats pour faciliter certains recodage, comme fct_collapse, qui propose une autre syntaxe pratique quand on doit regrouper ensemble des modalités :

hdv2003$qualif_rec <- fct_collapse(hdv2003$qualif,
  "Ouvrier" = c("Ouvrier specialise", "Ouvrier qualifie"),
  "Interm" = c("Technicien", "Profession intermediaire")
)

freq(hdv2003$qualif_rec)

fct_other, qui regroupe une liste de modalités en une seule modalité “Other” :

hdv2003$qualif_rec <- fct_other(hdv2003$qualif,
  drop = c(
    "Ouvrier specialise", "Ouvrier qualifie",
    "Cadre", "Autre"
  )
)

freq(hdv2003$qualif_rec)

fct_lump, qui regroupe automatiquement les modalités les moins fréquentes en une seule modalité “Other” (avec possibilité d’indiquer des seuils de regroupement) :

hdv2003$qualif_rec <- fct_lump(hdv2003$qualif)

freq(hdv2003$qualif_rec)

Ordonner les modalités d’une variable qualitative

L’avantage des facteurs (par rapport aux vecteurs de type character) est que leurs modalités peuvent être ordonnées, ce qui peut faciliter la lecture de tableaux ou graphiques.

On peut ordonner les modalités d’un facteur manuellement, par exemple avec la fonction fct_relevel() de l’extension forcats :

hdv2003$qualif_rec <- fct_relevel(
  hdv2003$qualif,
  "Cadre", "Profession intermediaire", "Technicien",
  "Employe", "Ouvrier qualifie", "Ouvrier specialise",
  "Autre"
)
freq(hdv2003$qualif_rec)

Une autre possibilité est d’ordonner les modalités d’un facteur selon les valeurs d’une autre variable. Par exemple, si on représente le boxplot de la répartition de l’âge selon le statut d’occupation :

library(ggplot2)
ggplot(hdv2003) +
  geom_boxplot(aes(x = occup, y = age))

Le graphique pourrait être plus lisible si les modalités étaient triées par âge median croissant. Ceci est possible en utilisant fct_reorder. Celle-ci prend 3 arguments : le facteur à réordonner, la variable dont les valeurs doivent être utilisées pour ce réordonnancement, et enfin une fonction à appliquer à cette deuxième variable.

hdv2003$occup_age <- fct_reorder(hdv2003$occup, hdv2003$age, median)

ggplot(hdv2003) +
  geom_boxplot(aes(x = occup_age, y = age))

Combiner plusieurs variables

Parfois, on veut créer une nouvelle variable en partant des valeurs d’une ou plusieurs autres variables. Dans ce cas on peut utiliser les fonctions if_else pour les cas les plus simples, ou case_when pour les cas plus complexes. Ces deux fonctions sont incluses dans l’extension dplyr, qu’il faut donc avoir chargé précédemment (voir le chapitre consacré à dplyr).

if_else

if_else prend trois arguments : un test, une valeur à renvoyer si le test est vrai, et une valeur à renvoyer si le test est faux.

Voici un exemple simple :

v <- c(12, 14, 8, 16)
if_else(v > 10, "Supérieur à 10", "Inférieur à 10")
[1] "Supérieur à 10" "Supérieur à 10" "Inférieur à 10"
[4] "Supérieur à 10"

La fonction devient plus intéressante avec des tests combinant plusieurs variables. Par exemple, imaginons qu’on souhaite créer une nouvelle variable indiquant les hommes de plus de 60 ans :

hdv2003$statut <- if_else(hdv2003$sexe == "Homme" & hdv2003$age > 60,
  "Homme de plus de 60 ans",
  "Autre"
)

freq(hdv2003$statut)

case_when

case_when est une génération du if_else qui permet d’indiquer plusieurs tests et leurs valeurs associées.

Imaginons qu’on souhaite créer une nouvelle variable permettant d’identifier les hommes de plus de 60 ans, les femmes de plus de 60 ans, et les autres. On peut utiliser la syntaxe suivante :

hdv2003$statut <- case_when(
  hdv2003$age > 60 & hdv2003$sexe == "Homme" ~ "Homme de plus de 60 ans",
  hdv2003$age > 60 & hdv2003$sexe == "Femme" ~ "Femme de plus de 60 ans",
  TRUE ~ "Autre"
)

freq(hdv2003$statut)

case_when prend en arguments une série d’instructions sous la forme condition ~ valeur. Il les exécute une par une, et dès qu’une condition est vraie, il renvoit la valeur associée.

La clause TRUE ~ "Autre" permet d’assigner une valeur à toutes les lignes pour lesquelles aucune des conditions précédentes n’est vraie.

Attention : comme les conditions sont testées l’une après l’autre et que la valeur renvoyée est celle correspondant à la première condition vraie, l’ordre de ces conditions est très important. Il faut absolument aller du plus spécifique au plus général.

Par exemple le recodage suivant ne fonctionne pas :

hdv2003$statut <- case_when(
  hdv2003$sexe == "Homme" ~ "Homme",
  hdv2003$sexe == "Homme" & hdv2003$age > 60 ~ "Homme de plus de 60 ans",
  TRUE ~ "Autre"
)

freq(hdv2003$statut)

Comme la condition sexe == "Homme" est plus générale que sexe == "Homme" & age > 60, cette deuxième condition n’est jamais testée ! On n’obtiendra jamais la valeur correspondante.

Pour que ce recodage fonctionne il faut donc changer l’ordre des conditions pour aller du plus spécifique au plus général :

hdv2003$statut <- case_when(
  hdv2003$sexe == "Homme" & hdv2003$age > 60 ~ "Homme de plus de 60 ans",
  hdv2003$sexe == "Homme" ~ "Homme",
  TRUE ~ "Autre"
)

freq(hdv2003$statut)

Vous pouvez trouver des exercices avec leur solution dans l’Introduction à R et au tidyverse de Julien Barnier.

Pour aller plus loin, R for Data Science de Garrett Grolemund et Hadley Wickham.

Recodage et data.table

Nous aborderons dans un prochain chapitre l’extension data.table qui étend les tableaux de données et modifie complètement la syntaxe utilisée entre les crochets. Elle nécessite un petit temps d’adaptation mais, une fois maîtrisée, elle facile le quotidien lorsqu’il s’agit de manipuler et recoder les données. Ci-dessous, un petit avant-goût, reprenons quelques exemples précédents.

library(data.table)
dt <- data.table(hdv2003)

dt[, score.ext := 0]
dt[cinema == "Oui", score.ext := score.ext + 10]
dt[peche.chasse == "Oui", score.ext := score.ext + 30]
dt[sport == "Oui", score.ext := score.ext + 20]
table(dt$score.ext)

dt[cuisine == "Oui" & bricol == "Oui", act.manuelles := "Cuisine et Bricolage"]
dt[cuisine == "Oui" & bricol == "Non", act.manuelles := "Cuisine seulement"]
dt[cuisine == "Non" & bricol == "Oui", act.manuelles := "Bricolage seulement"]
dt[cuisine == "Non" & bricol == "Non", act.manuelles := "Ni cuisine ni bricolage"]
table(dt$act.manuelles)

    Bricolage seulement    Cuisine et Bricolage 
                    437                     416 
      Cuisine seulement Ni cuisine ni bricolage 
                    465                     682 
dt[cuisine == "Oui" & bricol == "Oui", act.manuelles := "Cuisine et Bricolage"]
dt[cuisine == "Oui" & bricol == "Non", act.manuelles := "Cuisine seulement"]
dt[cuisine == "Non" & bricol == "Oui", act.manuelles := "Bricolage seulement"]
dt[cuisine == "Non" & bricol == "Non", act.manuelles := "Ni cuisine ni bricolage"]
table(dt$act.manuelles)

    Bricolage seulement    Cuisine et Bricolage 
                    437                     416 
      Cuisine seulement Ni cuisine ni bricolage 
                    465                     682 

  1. On priviligiera la fonction to_factor à la fonction as_factor de l’extension haven, la première ayant plus de possibilités et un comportement plus consistent.

Manipuler les données avec dplyr

La version originale de ce chapitre a été écrite par Julien Barnier dans le cadre de son Introduction à R et au tidyverse.

dplyr est une extension facilitant le traitement et la manipulation de données contenues dans une ou plusieurs tables (qu’il s’agisse de data frame ou de tibble). Elle propose une syntaxe claire et cohérente, sous formes de verbes, pour la plupart des opérations de ce type.

Par ailleurs, les fonctions de dplyr sont en général plus rapides que leur équivalent sous R de base, elles permettent donc de traiter des données de grande dimension1.

dplyr part du principe que les données sont tidy (voir la section consacrée aux tidy data). Les fonctions de l’extension peuvent s’appliquer à des tableaux de type data.frame ou tibble, et elles retournent systématiquement un tibble (voir la section dédiée).

Préparation

dplyr fait partie du coeur du tidyverse, elle est donc chargée automatiquement avec :

library(tidyverse)

On peut également la charger individuellement avec :

library(dplyr)

Dans ce qui suit on va utiliser les données du jeu de données nycflights13, contenu dans l’extension du même nom (qu’il faut donc avoir installé). Celui-ci correspond aux données de tous les vols au départ d’un des trois aéroports de New-York en 2013. Il a la particularité d’être réparti en trois tables :

  • flights contient des informations sur les vols : date, départ, destination, horaires, retard…
  • airports contient des informations sur les aéroports
  • airlines contient des données sur les compagnies aériennes

On va charger les trois tables du jeu de données :

library(nycflights13)
## Chargement des trois tables du jeu de données
data(flights)
data(airports)
data(airlines)

Normalement trois objets correspondant aux trois tables ont dû apparaître dans votre environnement.

Ces trois tableaux sont au format tibble. Il s’agit d’une extension des tableaux de données utilisé par le tidyverse. Les tibble{data-pkg="tibble} s’utilisent comme des data.frame, avec justes quelques différentes :

  • leur classe est c("tbl_df", "tbf", "data.frame") ;
  • leur présentation dans la console est amélioriée ;
  • df[, j] renvoie toujours un tibble avec une seule colonne (et non le contenu de cette colonne que l’on obtient avec df[[j]]) ;
  • les colonnes d’un tibble peuvent être des listes ;
  • à la différence d’un tableau de données classique où il est possible d’utiliser un nom partiel (par exemple écrire df$ab pour obtenir df$abc), il est obligatoire d’utiliser les noms complets avec un tibble.

Pour convertir un tableau de données en tibble, on utilisera la fonction as_tibble.

Les verbes de dplyr

La manipulation de données avec dplyr se fait en utilisant un nombre réduit de verbes, qui correspondent chacun à une action différente appliquée à un tableau de données.

slice

Le verbe slice sélectionne des lignes du tableau selon leur position. On lui passe un chiffre ou un vecteur de chiffres.

Si on souhaite sélectionner la 345e ligne du tableau airports :

slice(airports, 345)

Si on veut sélectionner les 5 premières lignes :

slice(airports, 1:5)

filter

filter sélectionne des lignes d’un tableau de données selon une condition. On lui passe en paramètre un test, et seules les lignes pour lesquelles ce test renvoit TRUE (vrai) sont conservées.

Par exemple, si on veut sélectionner les vols du mois de janvier, on peut filtrer sur la variable month de la manière suivante :

filter(flights, month == 1)

Si on veut uniquement les vols avec un retard au départ (variable dep_delay) compris entre 10 et 15 minutes :

filter(flights, dep_delay >= 10 & dep_delay <= 15)

Si on passe plusieurs arguments à filter, celui-ci rajoute automatiquement une condition et entre les conditions. La ligne ci-dessus peut donc également être écrite de la manière suivante, avec le même résultat :

filter(flights, dep_delay >= 10, dep_delay <= 15)

Enfin, on peut également placer des fonctions dans les tests, qui nous permettent par exemple de sélectionner les vols avec la plus grande distance :

filter(flights, distance == max(distance))

select, rename et relocate

select permet de sélectionner des colonnes d’un tableau de données. Ainsi, si on veut extraire les colonnes lat et lon du tableau airports :

select(airports, lat, lon)

Si on fait précéder le nom d’un -, la colonne est éliminée plutôt que sélectionnée :

select(airports, -lat, -lon)

select comprend toute une série de fonctions facilitant la sélection de multiples colonnes. Par exemple, starts_with, ends_width, contains ou matches permettent d’exprimer des conditions sur les noms de variables :

select(flights, starts_with("dep_"))

La syntaxe colonne1:colonne2 permet de sélectionner toutes les colonnes situées entre colonne1 et colonne2 incluses2 :

select(flights, year:day)

all_of et any_of permettent de fournir une liste de variables à extraire sous forme de vecteur textuel. Alors que all_of renverra une erreur si une variable n’est pas trouvée dans le tableau de départ, any_of sera moins stricte.

select(flights, all_of(c("year", "month", "day")))
select(flights, all_of(c("century", "year", "month", "day")))
Erreur : Can't subset columns that don't exist. 
x Column `century` doesn't exist.
select(flights, any_of(c("century", "year", "month", "day")))

where permets de sélectionner des variables à partir d’une fonction qui renvoie une valeur logique. Par exemple, pour sélectionner seulement les variables textuelles.

select(flights, where(is.character))

select peut être utilisée pour réordonner les colonnes d’une table en utilisant la fonction everything(), qui sélectionne l’ensemble des colonnes non encore sélectionnées. Ainsi, si on souhaite faire passer la colonne name en première position de la table airports, on peut faire :

select(airports, name, everything())

Pour réordonner des colonnes, on pourra aussi avoir recours à relocate en indiquant les premières variables. IL n’est pas nécessaire d’ajouter everything() car avec relocate toutes les variables sont conservées.

relocate(airports, lon, lat, name)

Une variante de select est rename3, qui permet de renommer facilement des colonnes. On l’utilise en lui passant des paramètres de la forme nouveau_nom = ancien_nom. Ainsi, si on veut renommer les colonnes lon et lat de airports en longitude et latitude :

rename(airports, longitude = lon, latitude = lat)

Si les noms de colonnes comportent des espaces ou des caractères spéciaux, on peut les entourer de guillemets (") ou de quotes inverses (`) :

tmp <- rename(flights, 
              "retard départ" = dep_delay,
              "retard arrivée" = arr_delay)
select(tmp, `retard départ`, `retard arrivée`)

arrange

arrange réordonne les lignes d’un tableau selon une ou plusieurs colonnes.

Ainsi, si on veut trier le tableau flights selon le retard au départ croissant :

arrange(flights, dep_delay)

On peut trier selon plusieurs colonnes. Par exemple selon le mois, puis selon le retard au départ :

arrange(flights, month, dep_delay)

Si on veut trier selon une colonne par ordre décroissant, on lui applique la fonction desc() :

arrange(flights, desc(dep_delay))

Combiné avec slice, arrange permet par exemple de sélectionner les trois vols ayant eu le plus de retard :

tmp <- arrange(flights, desc(dep_delay)) 
slice(tmp, 1:3)

mutate

mutate permet de créer de nouvelles colonnes dans le tableau de données, en général à partir de variables existantes.

Par exemple, la table airports contient l’altitude de l’aéroport en pieds. Si on veut créer une nouvelle variable alt_m avec l’altitude en mètres, on peut faire :

airports <- mutate(airports, alt_m = alt / 3.2808)
select(airports, name, alt, alt_m)

On peut créer plusieurs nouvelles colonnes en une seule fois, et les expressions successives peuvent prendre en compte les résultats des calculs précédents. L’exemple suivant convertit d’abord la distance en kilomètres dans une variable distance_km, puis utilise cette nouvelle colonne pour calculer la vitesse en km/h.

flights <- mutate(flights, 
                  distance_km = distance / 0.62137,
                  vitesse = distance_km / air_time * 60)
select(flights, distance, distance_km, vitesse)

À noter que mutate est évidemment parfaitement compatible avec les fonctions vues dans le chapitre sur les recodages : fonctions de forcats, if_else, case_when

L’avantage d’utiliser mutate est double. D’abord il permet d’éviter d’avoir à saisir le nom du tableau de données dans les conditions d’un if_else ou d’un case_when :

flights <- mutate(flights,
                  type_retard = case_when(
                    dep_delay > 0 & arr_delay > 0 ~ "Retard départ et arrivée",
                    dep_delay > 0 & arr_delay <= 0 ~ "Retard départ",
                    dep_delay <= 0 & arr_delay > 0 ~ "Retard arrivée",
                    TRUE ~ "Aucun retard"))

Utiliser mutate pour les recodages permet aussi de les intégrer dans un pipeline de traitement de données, concept présenté dans la section suivante.

Citons également les fonctions recode et recode_factor.

flights$month_name <- recode_factor(flights$month,
  "1" = "Jan",
  "2" = "Feb",
  "3" = "Mar",
  "4" = "Apr",
  "5" = "May",
  "6" = "Jun",
  "7" = "Jul",
  "8" = "Aug",
  "9" = "Sep",
  "10" = "Oct",
  "11" = "Nov",
  "12" = "Dec"
)

Enchaîner les opérations avec le pipe

Quand on manipule un tableau de données, il est très fréquent d’enchaîner plusieurs opérations. On va par exemple filtrer pour extraire une sous-population, sélectionner des colonnes puis trier selon une variable.

Dans ce cas on peut le faire de deux manières différentes. La première est d’effectuer toutes les opérations en une fois en les emboîtant :

arrange(select(filter(flights, dest == "LAX"), dep_delay, arr_delay), dep_delay)

Cette notation a plusieurs inconvénients :

  • elle est peu lisible
  • les opérations apparaissent dans l’ordre inverse de leur réalisation. Ici on effectue d’abord le filter, puis le select, puis le arrange, alors qu’à la lecture du code c’est le arrange qui apparaît en premier.
  • Il est difficile de voir quel paramètre se rapporte à quelle fonction

Une autre manière de faire est d’effectuer les opérations les unes après les autres, en stockant les résultats intermédiaires dans un objet temporaire :

tmp <- filter(flights, dest == "LAX")
tmp <- select(tmp, dep_delay, arr_delay)
arrange(tmp, dep_delay)

C’est nettement plus lisible, l’ordre des opérations est le bon, et les paramètres sont bien rattachés à leur fonction. Par contre, ça reste un peu “verbeux”, et on crée un objet temporaire tmp dont on n’a pas réellement besoin.

Pour simplifier et améliorer encore la lisibilité du code, on va utiliser un nouvel opérateur, baptisé pipe4. Le pipe se note %>%, et son fonctionnement est le suivant : si j’exécute expr %>% f, alors le résultat de l’expression expr, à gauche du pipe, sera passé comme premier argument à la fonction f, à droite du pipe, ce qui revient à exécuter f(expr).

Ainsi les deux expressions suivantes sont rigoureusement équivalentes :

filter(flights, dest == "LAX")
flights %>% filter(dest == "LAX")

Ce qui est intéressant dans cette histoire, c’est qu’on va pouvoir enchaîner les pipes. Plutôt que d’écrire :

select(filter(flights, dest == "LAX"), dep_delay, arr_delay)

On va pouvoir faire :

flights %>% filter(dest == "LAX") %>% select(dep_delay, arr_delay)

À chaque fois, le résultat de ce qui se trouve à gauche du pipe est passé comme premier argument à ce qui se trouve à droite : on part de l’objet flights, qu’on passe comme premier argument à la fonction filter, puis on passe le résultat de ce filter comme premier argument du select.

Le résultat final est le même avec les deux syntaxes, mais avec le pipe l’ordre des opérations correspond à l’ordre naturel de leur exécution, et on n’a pas eu besoin de créer d’objet intermédiaire.

Si la liste des fonctions enchaînées est longue, on peut les répartir sur plusieurs lignes à condition que l’opérateur %>% soit en fin de ligne :

flights %>% 
  filter(dest == "LAX") %>% 
  select(dep_delay, arr_delay) %>% 
  arrange(dep_delay)

On appelle une suite d’instructions de ce type un pipeline.

Évidemment, il est naturel de vouloir récupérer le résultat final d’un pipeline pour le stocker dans un objet. Par exemple, on peut stocker le résultat du pipeline ci-dessus dans un nouveau tableau delay_la de la manière suivante :

delay_la <- flights %>% 
  filter(dest == "LAX") %>% 
  select(dep_delay, arr_delay) %>% 
  arrange(dep_delay)

Dans ce cas, delay_la contiendra le tableau final, obtenu après application des trois instructions filter, select et arrange.

Cette notation n’est pas forcément très intuitive au départ. Il faut bien comprendre que c’est le résultat final, une fois application de toutes les opérations du pipeline, qui est renvoyé et stocké dans l’objet en début de ligne.

Une manière de le comprendre peut être de voir que la notation suivante :

delay_la <- flights %>% 
  filter(dest == "LAX") %>% 
  select(dep_delay, arr_delay)

est équivalente à :

delay_la <- (flights %>% filter(dest == "LAX") %>% select(dep_delay, arr_delay))

L’utilisation du pipe n’est pas obligatoire, mais elle rend les scripts plus lisibles et plus rapides à saisir. On l’utilisera donc dans ce qui suit.

Opérations groupées

group_by

Un élément très important de dplyr est la fonction group_by. Elle permet de définir des groupes de lignes à partir des valeurs d’une ou plusieurs colonnes. Par exemple, on peut grouper les vols selon leur mois :

flights %>% group_by(month)

Par défaut ceci ne fait rien de visible, à part l’apparition d’une mention Groups dans l’affichage du résultat. Mais à partir du moment où des groupes ont été définis, les verbes comme slice, mutate ou summarise vont en tenir compte lors de leurs opérations.

Par exemple, si on applique slice à un tableau préalablement groupé, il va sélectionner les lignes aux positions indiquées pour chaque groupe. Ainsi la commande suivante affiche le premier vol de chaque mois, selon leur ordre d’apparition dans le tableau :

flights %>% group_by(month) %>% slice(1)

Idem pour mutate : les opérations appliquées lors du calcul des valeurs des nouvelles colonnes sont aplliquée groupe de lignes par groupe de lignes. Dans l’exemple suivant, on ajoute une nouvelle colonne qui contient le retard moyen du mois correspondant :

flights %>% 
  group_by(month) %>% 
  mutate(mean_delay_month = mean(dep_delay, na.rm = TRUE)) %>% 
  select(dep_delay, month, mean_delay_month)

Ceci peut permettre, par exemple, de déterminer si un retard donné est supérieur ou inférieur au retard moyen du mois en cours.

group_by peut aussi être utile avec filter, par exemple pour sélectionner les vols avec le retard au départ le plus important pour chaque mois :

flights %>% 
  group_by(month) %>% 
  filter(dep_delay == max(dep_delay, na.rm = TRUE))

Attention : la clause group_by marche pour les verbes déjà vus précédemment, sauf pour arrange, qui par défaut trie la table sans tenir compte des groupes. Pour obtenir un tri par groupe, il faut lui ajouter l’argument .by_group = TRUE.

On peut voir la différence en comparant les deux résultats suivants :

flights %>% 
  group_by(month) %>% 
  arrange(desc(dep_delay))
flights %>% 
  group_by(month) %>% 
  arrange(desc(dep_delay), .by_group = TRUE)

summarise et count

summarise permet d’agréger les lignes du tableau en effectuant une opération “résumée” sur une ou plusieurs colonnes. Par exemple, si on souhaite connaître les retards moyens au départ et à l’arrivée pour l’ensemble des vols du tableau flights :

flights %>% 
  summarise(retard_dep = mean(dep_delay, na.rm=TRUE),
            retard_arr = mean(arr_delay, na.rm=TRUE))

Cette fonction est en général utilisée avec group_by, puisqu’elle permet du coup d’agréger et résumer les lignes du tableau groupe par groupe. Si on souhaite calculer le délai maximum, le délai minimum et le délai moyen au départ pour chaque mois, on pourra faire :

flights %>%
  group_by(month) %>%
  summarise(max_delay = max(dep_delay, na.rm=TRUE),
            min_delay = min(dep_delay, na.rm=TRUE),
            mean_delay = mean(dep_delay, na.rm=TRUE))
`summarise()` ungrouping output (override with `.groups` argument)

summarise dispose d’un opérateur spécial, n(), qui retourne le nombre de lignes du groupe. Ainsi si on veut le nombre de vols par destination, on peut utiliser :

flights %>%
  group_by(dest) %>%
  summarise(nb = n())
`summarise()` ungrouping output (override with `.groups` argument)

n() peut aussi être utilisée avec filter et mutate.

À noter que quand on veut compter le nombre de lignes par groupe, on peut utiliser directement la fonction count. Ainsi le code suivant est identique au précédent :

flights %>%
  count(dest)

Grouper selon plusieurs variables

On peut grouper selon plusieurs variables à la fois, il suffit de les indiquer dans la clause du group_by :

flights %>%
  group_by(month, dest) %>%
  summarise(nb = n()) %>%
  arrange(desc(nb))
`summarise()` regrouping output by 'month' (override with `.groups` argument)

On peut également compter selon plusieurs variables :

flights %>% 
  count(origin, dest) %>% 
  arrange(desc(n))

On peut utiliser plusieurs opérations de groupage dans le même pipeline. Ainsi, si on souhaite déterminer le couple origine/destination ayant le plus grand nombre de vols selon le mois de l’année, on devra procéder en deux étapes :

  • d’abord grouper selon mois, origine et destination pour calculer le nombre de vols
  • puis grouper uniquement selon le mois pour sélectionner la ligne avec la valeur maximale.

Au final, on obtient le code suivant :

flights %>%
  group_by(month, origin, dest) %>%
  summarise(nb = n()) %>%
  group_by(month) %>%
  filter(nb == max(nb))
`summarise()` regrouping output by 'month', 'origin' (override with `.groups` argument)

Lorsqu’on effectue un group_by suivi d’un summarise, le tableau résultat est automatiquement dégroupé de la dernière variable de regroupement. Ainsi le tableau généré par le code suivant est groupé par month et origin :

flights %>%
  group_by(month, origin, dest) %>%
  summarise(nb = n())
`summarise()` regrouping output by 'month', 'origin' (override with `.groups` argument)

Cela peut permettre “d’enchaîner” les opérations groupées. Dans l’exemple suivant on calcule le pourcentage des trajets pour chaque destination par rapport à tous les trajets du mois :

flights %>%
  group_by(month, dest) %>%
  summarise(nb = n()) %>% 
  mutate(pourcentage = nb / sum(nb) * 100)
`summarise()` regrouping output by 'month' (override with `.groups` argument)

On peut à tout moment “dégrouper” un tableau à l’aide de ungroup. Ce serait par exemple nécessaire, dans l’exemple précédent, si on voulait calculer le pourcentage sur le nombre total de vols plutôt que sur le nombre de vols par mois :

flights %>%
  group_by(month, dest) %>%
  summarise(nb = n()) %>% 
  ungroup() %>% 
  mutate(pourcentage = nb / sum(nb) * 100)
`summarise()` regrouping output by 'month' (override with `.groups` argument)

À noter que count, par contre, renvoit un tableau non groupé :

flights %>% 
  count(month, dest)

Autres fonctions utiles

dplyr contient beaucoup d’autres fonctions utiles pour la manipulation de données.

sample_n et sample_frac

sample_n et sample_frac permettent de sélectionner un nombre de lignes ou une fraction des lignes d’un tableau aléatoirement. Ainsi si on veut choisir 5 lignes au hasard dans le tableau airports :

airports %>% sample_n(5)

Si on veut tirer au hasard 10% des lignes de flights :

flights %>% sample_frac(0.1)

Ces fonctions sont utiles notamment pour faire de “l’échantillonnage” en tirant au hasard un certain nombre d’observations du tableau.

lead et lag

lead et lag permettent de décaler les observations d’une variable d’un cran vers l’arrière (pour lead) ou vers l’avant (pour lag).

lead(1:5)
[1]  2  3  4  5 NA
lag(1:5)
[1] NA  1  2  3  4

Ceci peut être utile pour des données de type “séries temporelles”. Par exemple, on peut facilement calculer l’écart entre le retard au départ de chaque vol et celui du vol précédent :

flights %>%
  mutate(dep_delay_prev = lead(dep_delay),
         dep_delay_diff = dep_delay - dep_delay_prev) %>%
  select(dep_delay_prev, dep_delay, dep_delay_diff)

tally

tally est une fonction qui permet de compter le nombre d’observations d’un groupe :

flights %>% 
  group_by(month, origin, dest) %>% 
  tally

Lors de son premier appel, elle sera équivalente à un summarise(n = n()) ou à un count(). Là où la fonction est intelligente, c’est que si on l’appelle plusieurs fois successivement, elle prendra en compte l’existence d’un n déjà calculé et effectuera automatiquement un summarise(n = sum(n)) :

flights %>% 
  group_by(month, origin, dest) %>% 
  tally %>%
  tally

distinct

distinct filtre les lignes du tableau pour ne conserver que les lignes distinctes, en supprimant toutes les lignes en double.

flights %>%
  select(day, month) %>%
  distinct

On peut lui spécifier une liste de variables : dans ce cas, pour toutes les observations ayant des valeurs identiques pour les variables en question, distinct ne conservera que la première d’entre elles.

flights %>%
  distinct(month, day)

L’option .keep_all permet, dans l’opération précédente, de conserver l’ensemble des colonnes du tableau :

flights %>%
  distinct(month, day, .keep_all = TRUE) 

Ressources

Toutes les ressources ci-dessous sont en anglais…

Le livre R for data science, librement accessible en ligne, contient plusieurs chapitres très complets sur la manipulation des données, notamment :

Le site de l’extension comprend une liste des fonctions et les pages d’aide associées, mais aussi une introduction au package et plusieurs articles dont un spécifiquement sur les jointures.

Une “antisèche” très synthétique est également accessible depuis RStudio, en allant dans le menu Help puis Cheatsheets et Data Transformation with dplyr.

Enfin, on trouvera des exercices dans l’Introduction à R et au tidyverse de Julien Barnier.

dplyr et data.table

Pour ceux travaillant également avec l’extension data.table, il est possible de concilier tibble et data.table avec l’extension dtplyr. Cette extension a connu une profonde évolution en 2019. Pour plus d’informations, voir https://dtplyr.tidyverse.org/. Pour décrouvrir data.table, voir le chapitre dédié.

dplyr et survey

L’extension srvyr vise à permettre d’utiliser les verbes de dplyr avec les plans d’échantillonnage complexe définis avec survey. Le fonctionnement de cette extension est expliqué dans une vignette dédiée : https://cran.r-project.org/web/packages/srvyr/vignettes/srvyr-vs-survey.html.


  1. Elles sont cependant moins rapides que les fonctions de data.table, voir le chapitre dédié

  2. À noter que cette opération est un peu plus “fragile” que les autres, car si l’ordre des colonnes change elle peut renvoyer un résultat différent.

  3. Il est également possible de renommer des colonnes directement avec select, avec la même syntaxe que pour rename.

  4. Le pipe a été introduit à l’origine par l’extension magrittr, et repris par dplyr

Manipulations avancées avec data.table

L’extension data.table permets d’étendre les tableaux de données. Elle modifie radicalement la syntaxe des crochets, permettant un code plus court et surtout plus puissant. Par ailleurs, elle est particulièrement rapide pour opérer des opérations sur les données et permets d’effectuer des opérations par assignation directe sans avoir à copier les objets en mémoire. Autrement dit, elle est particulièrement utile lorsque l’on travaille sur des gros fichiers de données.

Certes, l’apprentissage de cette nouvelle syntaxe peut faire peur au début, mais c’est un gain tellement notable une fois qu’on la maîtrise, qu’il est difficile de revenir en arrière.

Pour un tutoriel (en anglais et en ligne) écrit par les développeurs de data.table, voir https://www.datacamp.com/courses/data-table-data-manipulation-r-tutorial. On pourra aussi se référer au site officiel et ses différentes vignettes (en anglais) : https://rdatatable.gitlab.io/.

Convertir un data.frame en data.table

Il suffit d’avoir recours à la fonction as.data.table.

library(data.table)
iris2 <- as.data.table(iris)
class(iris2)
[1] "data.table" "data.frame"

Comme on le voit, cela ajoute plusieurs classes additionnelles au tableau de données, celui-ci restant malgré tout toujours un data.frame. Cependant, la syntaxe des crochets simples [] change radicalement, tandis que les crochets doubles [[]] restent inchangés. Par contre, comme il s’agit toujours d’un tableau de données classique, on pourra l’utiliser avec les fonctions des autres extensions de R. Si jamais vous rencontriez un problème, il est toujours possible de reconvertir en tableau de données classique avec setDF (voir ci-dessous).

setDT et setDF

Lors de l’utilisation de as.data.table, le tableau de données original a d’abord été copié en mémoire, converti puis il a fallu le sauvegarder dans un objet avec <-. Lorsqu’on l’on manipule de gros tableaux, cela est gourmand en ressources système et prend du temps.

C’est pour cela que data.table fournie plusieurs fonctions (commençant parle préfixe set) qui modifient directement l’objet sélectionné en mémoire, ce qu’on appelle modification par assignation. Ce type de fonction est beaucoup plus rapide et efficace en termes de ressources système. On notera également qu’il est inutile de stocker le résultats dans un objet puisque l’objet a été modifié directement en mémoire.

setDT converti un tableaux de données en data.table tandis que setDF fait l’opération opposée.

setDT(iris)
class(iris)
[1] "data.table" "data.frame"
setDF(iris)
class(iris)
[1] "data.frame"

dplyr et data.table

Pour ceux travaillant également avec les extension dplyr et tibble, il est possible de concilier tibble et data.table avec l’extension dtplyr. Cette extension a connu une profonde évolution en 2019. Pour plus d’informations, voir https://dtplyr.tidyverse.org/.

La syntaxe des crochets

La syntaxe des crochets change radicalement avec data.table. Elle est de la forme objet[i, j, by] (dans sa forme la plus simple, pour une présentation exhaustive, voir le fichier d’aide de data.table-package).

Sélectionner des observations

Cela se fait en indiquant une indiquant une condition au premier argument, à savoir i. Si l’on ne procède à une sélection en même temps sur les variables, il n’est pas nécessaire d’indiquer de virgule , dans les crochets.

iris2[Sepal.Length < 5]

On notera que les noms indiquer entre les crochets sont évalués en fonction du contexte, en l’occurence la liste des variables de l’objet considéré. Ainsi, les noms des variables peuvent être indiqués tels quels, sans utilisation du symbole $ ni des guillemets.

Une différence de taille : lorsqu’il y a des observations pour lesquelles la condition indiquée en i renvoie NA, elles ne sont pas sélectionnées par data.table tandis que, pour un data.frame classique cela renvoie des lignes manquantes.

Sélectionner des variables

Pour sélectionner une variable, il suffit d’indiquer son nom dans la seconde partie, à savoir j. Noter la virgule qui permets d’indiquer que c’est une condition sur j et non sur i.

iris2[, Sepal.Length]
  [1] 5.1 4.9 4.7 4.6 5.0 5.4 4.6 5.0 4.4 4.9 5.4 4.8 4.8
 [14] 4.3 5.8 5.7 5.4 5.1 5.7 5.1 5.4 5.1 4.6 5.1 4.8 5.0
 [27] 5.0 5.2 5.2 4.7 4.8 5.4 5.2 5.5 4.9 5.0 5.5 4.9 4.4
 [40] 5.1 5.0 4.5 4.4 5.0 5.1 4.8 5.1 4.6 5.3 5.0 7.0 6.4
 [53] 6.9 5.5 6.5 5.7 6.3 4.9 6.6 5.2 5.0 5.9 6.0 6.1 5.6
 [66] 6.7 5.6 5.8 6.2 5.6 5.9 6.1 6.3 6.1 6.4 6.6 6.8 6.7
 [79] 6.0 5.7 5.5 5.5 5.8 6.0 5.4 6.0 6.7 6.3 5.6 5.5 5.5
 [92] 6.1 5.8 5.0 5.6 5.7 5.7 6.2 5.1 5.7 6.3 5.8 7.1 6.3
[105] 6.5 7.6 4.9 7.3 6.7 7.2 6.5 6.4 6.8 5.7 5.8 6.4 6.5
[118] 7.7 7.7 6.0 6.9 5.6 7.7 6.3 6.7 7.2 6.2 6.1 6.4 7.2
[131] 7.4 7.9 6.4 6.3 6.1 7.7 6.3 6.4 6.0 6.9 6.7 6.9 5.8
[144] 6.8 6.7 6.7 6.3 6.5 6.2 5.9

Pour sélectionner plusieurs variables, on fournira une liste définie avec list (et non un vecteur défini avec c).

iris2[, list(Sepal.Length, Sepal.Width)]

data.table fourni un raccourci pour écrire une liste : .(). A l’intérieur des crochets (mais pas en dehors), .() sera compris comme list().

iris2[, .(Sepal.Length, Sepal.Width)]

Il est possible de renommer une variable à la volée et même d’en calculer d’autres.

iris2[, .(espece = Species, aire_petal = Petal.Length * Petal.Width)]

Seul le retour est ici affecté. Cela n’impacte pas le tableau d’origine. Nous verrons plus loin comment créer / modifier une variable.

Attention : on ne peut pas directement sélectionner une variable par sa position ou en indiquant une chaîne de caractères. En effet, une valeur numérique ou textuelle est comprise comme une constante.

iris2[, .("Species", 3)]

Grouper les résultats

Si en j on utilise des fonctions qui à partir d’un vecteur renvoient une valeur unique (telles que mean, median, min, max, first, last, nth, etc.), on peut ainsi obtenir un résumé. On pourra également utiliser .N pour obtenir le nombre d’observations.

iris2[, .(min_sepal_width = min(Sepal.Width), max_sepal_width = max(Sepal.Width), n_observations = .N)]

Cela devient particulièrement intéressant en calculant ces mêmes valeurs par sous-groupe, grace au troisième paramètre : by.

iris2[, .(min_sepal_width = min(Sepal.Width), max_sepal_width = max(Sepal.Width), n_observations = .N), by = Species]

Ajouter / Modifier / Supprimer une variable

data.table introduit un nouvel opérateur := permettant de modifier une variable par assignation directe. Cela signifie que la modification a lieu directement en mémoire dans le tableau de données, sans qu’il soit besoin réaffecter le résultat avec <-.

On peut également combiner := avec une sélection sur les observations en i pour ne modifier que certaines observations. De même, le recours à by permets des calculs par groupe.

iris2[, group := "A"]
iris2[Species == "virginica", group := "B"]
iris2[, n_obs_per_species := .N, by = Species]
iris2
iris2[, .N, by = group]

Enchaîner les opérations

Il est possible d’enchaîner les opérations avec une succession de crochets.

iris2[, .(petal_area = Petal.Width * Petal.Length, Species)][, .(min_petal_area = min(petal_area)), by = Species]

Réorganiser un tableau

L’extension data.table fournie également deux fonctions, melt et dcast, dédiée à la réorganisation d’un tableau de données (respectivement wide-to-long reshaping et long-to-wide reshaping).

Pour plus de détails, voir la vignette dédiée sur le site de l’extension : https://rdatatable.gitlab.io/data.table/articles/datatable-reshape.html

Tris

Dans ce qui suit on travaillera sur le jeu de données tiré de l’enquête Histoire de vie, fourni avec l’extension questionr.

library(questionr)
data(hdv2003)
d <- hdv2003

Fonctions R de base

La fonction sort permet de trier les éléments d’un vecteur.

sort(c(2, 5, 6, 1, 8))
[1] 1 2 5 6 8

On peut appliquer cette fonction à une variable, mais celle-ci ne permet que d’ordonner les valeurs de cette variable, et pas l’ensemble du tableau de données dont elle fait partie. Pour cela nous avons besoin d’une autre fonction, nommée order. Celle-ci ne renvoie pas les valeurs du vecteur triées, mais les emplacements de ces valeurs.

Un exemple pour comprendre :

order(c(15, 20, 10))
[1] 3 1 2

Le résultat renvoyé signifie que la plus petite valeur est la valeur située en 3e position, suivie de celle en 1ère position et de celle en 2e position. Tout cela ne paraît pas passionnant à première vue, mais si on mélange ce résultat avec un peu d’indexation directe, ça devient intéressant…

head(order(d$age))
[1] 162 215 346 377 511 646

Ce que cette fonction renvoie, c’est l’ordre dans lequel on doit placer les éléments de age, et donc par extension les lignes de d, pour que la variable soit triée par ordre croissant. Par conséquent, si on fait :

d.tri <- d[order(d$age), ]

Alors on a trié les lignes de d par ordre d’âge croissant ! Et si on fait un petit :

head(d.tri, 3)
id age sexe nivetud poids occup qualif freres.soeurs clso relig trav.imp trav.satisf hard.rock lecture.bd peche.chasse cuisine bricol cinema sport heures.tv
162 162 18 Homme NA 4982.964 Etudiant, eleve NA 2 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Oui 3
215 215 18 Homme NA 4631.188 Etudiant, eleve NA 2 Oui Ni croyance ni appartenance NA NA Non Non Non Oui Non Oui Oui 2
346 346 18 Femme NA 1725.410 Etudiant, eleve NA 9 Non Pratiquant regulier NA NA Non Non Non Non Non Oui Non 2

On a les caractéristiques des trois enquêtés les plus jeunes.

On peut évidemment trier par ordre décroissant en utilisant l’option decreasing=TRUE. On peut donc afficher les caractéristiques des trois individus les plus âgés avec :

head(d[order(d$age, decreasing = TRUE), ], 3)
id age sexe nivetud poids occup qualif freres.soeurs clso relig trav.imp trav.satisf hard.rock lecture.bd peche.chasse cuisine bricol cinema sport heures.tv
1916 1916 97 Femme Derniere annee d’etudes primaires 2162.835 Autre inactif Autre 5 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 3
270 270 96 Femme Derniere annee d’etudes primaires 9993.020 Retraite NA 1 Oui Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 6
1542 1542 93 Femme Derniere annee d’etudes primaires 7107.841 Retire des affaires NA 7 Non Pratiquant occasionnel NA NA Non Non Non Non Non Oui Non 3

On peut également trier selon plusieurs variables. Ainsi, si l’on souhaite trier le tableau par sexe puis, au sein de chaque sexe, par age :

d.tri <- d[order(d$sexe, d$age), ]

Si l’on transmets une variable textuelle, le tri sera réalisé de manière alphabétique alors que si l’on transmets un facteur, le tri sera effectué selon l’ordre des facteurs (que l’on peut visualiser avec levels).

Extension dplyr

On aura simplement recours à la fonction arrange. Un tri par ordre décroissant s’indique avec la fonction desc.

library(dplyr)
tbl <- as_tibble(hdv2003)
tbl <- tbl %>% arrange(sexe, desc(age))

Extension data.table

On pourra utiliser la fonction order dans la condition sur les observations (attention à sauvegarder le résultats si nécessaire) ou bien la fonction setorder pour modifier l’ordre des observations directement par assignation (modification directe en mémoire de l’objet). Un tri décroissant s’indique avec le signe -.

library(data.table)
dt <- as.data.table(hdv2003)

# Option 1
dt <- dt[order(sexe, -age)]

# Option 2
setorder(dt, sexe, -age)

Sous-ensembles

Dans ce qui suit on travaillera sur le jeu de données tiré de l’enquête Histoire de vie, fourni avec l’extension questionr.

library(questionr)
data(hdv2003)
d <- hdv2003

Par indexation

La première manière de construire des sous-populations est d’utiliser l’indexation par conditions. On peut ainsi facilement sélectionner une partie des observations suivant un ou plusieurs critères et placer le résultat dans un nouveau tableau de données.

Par exemple si l’on souhaite isoler les hommes et les femmes :

dh <- d[d$sexe == "Homme", ]
df <- d[d$sexe == "Femme", ]
table(d$sexe)
Homme Femme
899 1101
dim(dh)
[1] 899  20
dim(df)
[1] 1101   20

On a à partir de là trois tableaux de données, d comportant la population totale, dh seulement les hommes et df seulement les femmes.

On peut évidemment combiner plusieurs critères :

dh.25 <- d[d$sexe == "Homme" & d$age <= 25, ]
dim(dh.25)
[1] 86 20

Si on utilise directement l’indexation, il convient cependant d’être extrêmement prudent avec les valeurs manquantes. Comme indiqué précédemment, la présence d’une valeur manquante dans une condition fait que celle-ci est évaluée en NA et qu’au final la ligne correspondante est conservée par l’indexation :

summary(d$trav.satisf)
  Satisfaction Insatisfaction      Equilibre           NA's 
           480            117            451            952 
d.satisf <- d[d$trav.satisf == "Satisfaction", ]
dim(d.satisf)
[1] 1432   20

Comme on le voit, ici d.satisf contient les individus ayant la modalité Satisfaction mais aussi ceux ayant une valeur manquante NA. C’est pourquoi il faut toujours soit vérifier au préalable qu’on n’a pas de valeurs manquantes dans les variables de la condition, soit exclure explicitement les NA de la manière suivante :

d.satisf <- d[d$trav.satisf == "Satisfaction" & !is.na(d$trav.satisf), ]
dim(d.satisf)
[1] 480  20

C’est notamment pour cette raison qu’on préfèrera le plus souvent utiliser la fonction subset.

Fonction subset

La fonction subset permet d’extraire des sous-populations de manière plus simple et un peu plus intuitive que l’indexation directe.

Celle-ci prend trois arguments principaux :

  • le nom de l’objet de départ ;
  • une condition sur les observations (subset) ;
  • éventuellement une condition sur les colonnes (select).

Reprenons tout de suite un exemple déjà vu :

dh <- subset(d, sexe == "Homme")
df <- subset(d, sexe == "Femme")

L’utilisation de subset présente plusieurs avantages. Le premier est d’économiser quelques touches. On n’est en effet pas obligé de saisir le nom du tableau de données dans la condition sur les lignes. Ainsi les deux commandes suivantes sont équivalentes :

dh <- subset(d, d$sexe == "Homme")
dh <- subset(d, sexe == "Homme")

Le second avantage est que subset s’occupe du problème des valeurs manquantes évoquées précédemment et les exclut de lui-même, contrairement au comportement par défaut :

summary(d$trav.satisf)
  Satisfaction Insatisfaction      Equilibre           NA's 
           480            117            451            952 
d.satisf <- d[d$trav.satisf == "Satisfaction", ]
dim(d.satisf)
[1] 1432   20
d.satisf <- subset(d, trav.satisf == "Satisfaction")
dim(d.satisf)
[1] 480  20

Dans le cas présent, l’extraction obtenue avec subset est équivalente à :

d.satisf <- d[d$trav.satisf == "Satisfaction" & !is.na(d$trav.satisf), ]
dim(d.satisf)
[1] 480  20

Enfin, l’utilisation de l’argument select est simplifié pour l’expression de condition sur les colonnes. On peut ainsi spécifier les noms de variable sans guillemets et leur appliquer directement l’opérateur d’exclusion - :

d2 <- subset(d, select = c(sexe, sport))
d2 <- subset(d, age > 25, select = -c(id, age, cinema))

Fonction tapply

Cette section documente une fonction qui peut être très utile, mais pas forcément indispensable au départ.

La fonction tapply n’est qu’indirectement liée à la notion de sous-population, mais peut permettre d’éviter d’avoir à créer ces sous-populations dans certains cas.

Son fonctionnement est assez simple, mais pas forcément intuitif. La fonction prend trois arguments : un vecteur, un facteur et une fonction. Elle applique ensuite la fonction aux éléments du vecteur correspondant à un même niveau du facteur. Vite, un exemple !

tapply(d$age, d$sexe, mean)
   Homme    Femme 
48.16129 48.15350 

Qu’est-ce que ça signifie ? Ici tapply a sélectionné toutes les observations correspondant à « Homme », puis appliqué la fonction mean aux valeurs de age correspondantes. Puis elle a fait de même pour les observations correspondant à « Femme ». On a donc ici la moyenne d’âge chez les hommes et chez les femmes.

On peut fournir à peu près n’importe quelle fonction à tapply :

tapply(d$bricol, d$sexe, freq)
$Homme
      n    % val%
Non 384 42.7 42.7
Oui 515 57.3 57.3

$Femme
      n    % val%
Non 763 69.3 69.3
Oui 338 30.7 30.7

Les arguments supplémentaires fournis à tapply sont en fait fournis directement à la fonction appelée.

tapply(d$bricol, d$sexe, freq, total = TRUE)
$Homme
        n     %  val%
Non   384  42.7  42.7
Oui   515  57.3  57.3
Total 899 100.0 100.0

$Femme
         n     %  val%
Non    763  69.3  69.3
Oui    338  30.7  30.7
Total 1101 100.0 100.0

La fonction by est un équivalent (pour les tableaux de données) de tapply. La présentation des résultats diffère légèrement.

tapply(d$age, d$sexe, mean)
   Homme    Femme 
48.16129 48.15350 
by(d$age, d$sexe, mean)
d$sexe: Homme
[1] 48.16129
--------------------------------------------- 
d$sexe: Femme
[1] 48.1535

Extension dplyr

On utilisera tout simplement la fonction filter.

library(dplyr)
tbl <- as_tibble(hdv2003)
hommes_jeunes <- tbl %>% filter(sexe == "Homme", age < 30)

Voir le chapitre dédié à dplyr pour plus de détails.

Extension data.table

Il suffit d’indiquer la condition entre crochets.

library(data.table)
dt <- as.data.table(hdv2003)
hommes_jeunes <- dt[sexe == "Hommes" & age < 30]

Il est également possible d’utiliser la fonction subset sur un data.table.

hommes_jeunes <- subset(dt, sexe == "Hommes" & age < 30)

Voir le chapitre dédié à data.table pour plus de détails.

Fusion de tables

Lorsqu’on traite de grosses enquêtes, notamment les enquêtes de l’INSEE, on a souvent à gérer des données réparties dans plusieurs tables, soit du fait de la construction du questionnaire, soit du fait de contraintes techniques (fichiers dbf ou Excel limités à 256 colonnes, par exemple).

Cela arrive également lorsque l’on traitre de données d’une enquêtes réalisée à différents niveaux (par exemple, un questionnaire ménage et un questionnaire individu).

On peut distinguer deux situations :

La fonction merge et les jointures

Une opération relativement courante consiste à fusionner plusieurs tables pour regrouper tout ou partie des données dans un unique tableau.

Nous allons simuler artificiellement une telle situation en créant deux tables à partir de l’extrait de l’enquête Histoire de vie :

library(questionr)
data(hdv2003)
d <- hdv2003
dim(d)
[1] 2000   20
d1 <- subset(d, select = c("id", "age", "sexe"))
dim(d1)
[1] 2000    3
d2 <- subset(d, select = c("id", "clso"))
dim(d2)
[1] 2000    2

On a donc deux tableaux de données, d1 et d2, comportant chacun 2000 lignes et respectivement 3 et 2 colonnes. Comment les rassembler pour n’en former qu’un ?

Intuitivement, cela paraît simple. Il suffit de « coller » d2 à la droite de d1, comme dans l’exemple suivant.

id v1 v2
1 H 12
2 H 17
3 F 41
4 F 9
+
id v3
1 rouge
2 bleu
3 bleu
4 rouge
=
id v1 v2 v3
1 H 12 rouge
2 H 17 bleu
3 F 41 bleu
4 F 9 rouge

Cela semble fonctionner. La fonction qui permet d’effectuer cette opération sous R s’appelle cbind, elle « colle » des tableaux côte à côte en regroupant leurs colonnes.

head(cbind(d1, d2))

À part le fait qu’on a une colonne id en double, le résultat semble satisfaisant. À première vue seulement. Imaginons maintenant que nous avons travaillé sur d1 et d2, et que nous avons ordonné les lignes de d1 selon l’âge des enquêtés :

d1 <- d1[order(d1$age), ]

Répétons l’opération de collage :

head(cbind(d1, d2))

Que constate-t-on ? La présence de la variable id en double nous permet de voir que les identifiants ne coïncident plus ! En regroupant nos colonnes nous avons donc attribué à des individus les réponses d’autres individus.

La commande cbind ne peut en effet fonctionner que si les deux tableaux ont exactement le même nombre de lignes, et dans le même ordre, ce qui n’est pas le cas ici.

Pour éviter toute erreur, il est préférable de ne jamais utiliser cbind ou son équivalent bind_cols fournis par dplyr.

On aura recours à la jointure entre tables présentée ci-dessous.

On va donc être obligé de procéder à une fusion des deux tableaux, qui va permettre de rendre à chaque ligne ce qui lui appartient. Pour cela nous avons besoin d’un identifiant qui permet d’identifier chaque ligne de manière unique et qui doit être présent dans tous les tableaux. Dans notre cas, c’est plutôt rapide, il s’agit de la variable id.

Une fois l’identifiant identifié1, on peut utiliser la commande merge. Celle-ci va fusionner les deux tableaux en supprimant les colonnes en double et en regroupant les lignes selon leurs identifiants :

d.complet <- merge(d1, d2, by = "id")
head(d.complet)

Ici l’utilisation de la fonction merge est plutôt simple car nous sommes dans le cas de figure idéal : les lignes correspondent parfaitement et l’identifiant est clairement identifié. Parfois les choses peuvent être un peu plus compliquées :

  • parfois les identifiants n’ont pas le même nom dans les deux tableaux. On peut alors les spécifier par les options by.x et by.y ;
  • parfois les deux tableaux comportent des colonnes (hors identifiants) ayant le même nom. merge conserve dans ce cas ces deux colonnes mais les renomme en les suffixant par .x pour celles provenant du premier tableau et .y pour celles du second ;
  • parfois on n’a pas d’identifiant unique préétabli, mais on en construit un à partir de plusieurs variables. On peut alors donner un vecteur en paramètres de l’option by, par exemple by=c("nom","prenom","date.naissance").

Une subtilité supplémentaire intervient lorsque les deux tableaux fusionnés n’ont pas exactement les mêmes lignes. Par défaut, merge ne conserve que les lignes présentes dans les deux tableaux :

id v1
1 H
2 H
3 F
+
id v2
1 10
2 15
5 31
=
id v1 v2
1 H 10
2 H 15

On peut cependant modifier ce comportement avec les options all.x et all.y.

Ainsi, all.x = TRUE indique de conserver toutes les lignes du premier tableau. Dans ce cas merge donne une valeur NA pour ces lignes aux colonnes provenant du second tableau. Ce qui donnerait :

id v1
1 H
2 H
3 F
+
id v2
1 10
2 15
5 31
=
id v1 v2
1 H 10
2 H 15
3 F NA

L’option all.y = TRUE fait la même chose en conservant toutes les lignes du second tableau.

id v1
1 H
2 H
3 F
+
id v2
1 10
2 15
5 31
=
id v1 v2
1 H 10
2 H 15
5 NA 31

Enfin, on peut décider de conserver toutes les lignes des deux tableaux en utilisant à la fois all.x = TRUE et all.y = TRUE, ce qui donne :

id v1
1 H
2 H
3 F
+
id v2
1 10
2 15
5 31
=
id v1 v2
1 H 10
2 H 15
3 F NA
5 NA 31

Parfois, l’un des identifiants est présent à plusieurs reprises dans l’un des tableaux (par exemple lorsque l’une des tables est un ensemble de ménages et que l’autre décrit l’ensemble des individus de ces ménages). Dans ce cas les lignes de l’autre table sont dupliquées autant de fois que nécessaires :

id v1
1 H
2 H
3 F
+
id v2
1 10
1 18
1 21
2 15
3 42
=
id v1 v2
1 H 10
1 H 18
1 H 21
2 H 15
3 F 42

Jointures avec dplyr

Le jeu de données nycflights13 est un exemple de données réparties en plusieurs tables. Ici on en a trois : les informations sur les vols, celles sur les aéroports et celles sur les compagnies aériennes sont dans trois tables distinctes.

dplyr propose différentes fonctions permettant de travailler avec des données structurées de cette manière.

library(tidyverse)
library(nycflights13)
data(flights)
data(airports)
data(airlines)

Clés implicites

Très souvent, les données relatives à une analyse sont réparties dans plusieurs tables différentes. Dans notre exemple, on peut voir que la table flights contient seulement le code de la compagnie aérienne du vol dans la variable carrier :

flights %>% select(carrier)

Et que par ailleurs la table airlines contient une information supplémentaire relative à ces compagnies, à savoir le nom complet.

airlines

Il est donc naturel de vouloir associer les deux, en l’occurrence pour ajouter les noms complets des compagnies à la table flights. Dans ce cas on va faire une jointure : les lignes d’une table seront associées à une autre en se basant non pas sur leur position, mais sur les valeurs d’une ou plusieurs colonnes. Ces colonnes sont appelées des clés.

Pour faire une jointure de ce type, on va utiliser la fonction left_join :

left_join(flights, airlines)

Pour faciliter la lecture, on va afficher seulement certaines colonnes du résultat :

left_join(flights, airlines) %>%
  select(month, day, carrier, name)
Joining, by = "carrier"

On voit que la table résultat est bien la fusion des deux tables d’origine selon les valeurs des deux colonnes clés carrier. On est parti de la table flights, et pour chaque ligne on a ajouté les colonnes de airlines pour lesquelles la valeur de carrier est la même. On a donc bien une nouvelle colonne name dans notre table résultat, avec le nom complet de la compagnie aérienne.

À noter qu’on peut tout à fait utiliser le pipe avec les fonctions de jointure :

flights %>% left_join(airlines).

Nous sommes ici dans le cas le plus simple concernant les clés de jointure : les deux clés sont uniques et portent le même nom dans les deux tables. Par défaut, si on ne lui spécifie pas explicitement les clés, dplyr fusionne en utilisant l’ensemble des colonnes communes aux deux tables. On peut d’ailleurs voir dans cet exemple qu’un message a été affiché précisant que la jointure s’est faite sur la variable carrier.

Clés explicites

La table airports, elle, contient des informations supplémentaires sur les aéroports : nom complet, altitude, position géographique, etc. Chaque aéroport est identifié par un code contenu dans la colonne faa.

Si on regarde la table flights, on voit que le code d’identification des aéroports apparaît à deux endroits différents : pour l’aéroport de départ dans la colonne origin, et pour celui d’arrivée dans la colonne dest. On a donc deux clés de jointures possibles, et qui portent un nom différent de la clé de airports.

On va commencer par fusionner les données concernant l’aéroport de départ. Pour simplifier l’affichage des résultats, on va se contenter d’un sous-ensemble des deux tables :

flights_ex <- flights %>% select(month, day, origin, dest)
airports_ex <- airports %>% select(faa, alt, name)

Si on se contente d’un left_join comme à l’étape précédente, on obtient un message d’erreur car aucune colonne commune ne peut être identifiée comme clé de jointure :

left_join(flights_ex, airports_ex)
Error: `by` must be supplied when `x` and `y` have no common variables.
i use by = character()` to perform a cross-join.

On doit donc spécifier explicitement les clés avec l’argument by de left_join. Ici la clé est nommée origin dans la première table, et faa dans la seconde. La syntaxe est donc la suivante :

left_join(flights_ex, airports_ex, by = c("origin" = "faa"))

On constate que les deux nouvelles colonnes name et alt contiennent bien les données correspondant à l’aéroport de départ.

On va stocker le résultat de cette jointure dans flights_ex :

flights_ex <- flights_ex %>%
  left_join(airports_ex, by = c("origin" = "faa"))

Supposons qu’on souhaite maintenant fusionner à nouveau les informations de la table airports, mais cette fois pour les aéroports d’arrivée de notre nouvelle table flights_ex. Les deux clés sont donc désormais dest dans la première table, et faa dans la deuxième. La syntaxe est donc la suivante :

left_join(flights_ex, airports_ex, by = c("dest" = "faa"))

Cela fonctionne, les informations de l’aéroport d’arrivée ont bien été ajoutées, mais on constate que les colonnes ont été renommées. En effet, ici les deux tables fusionnées contenaient toutes les deux des colonnes name et alt. Comme on ne peut pas avoir deux colonnes avec le même nom dans un tableau, dplyr a renommé les colonnes de la première table en name.x et alt.x, et celles de la deuxième en name.y et alt.y.

C’est pratique, mais pas forcément très parlant. On pourrait renommer manuellement les colonnes pour avoir des intitulés plus explicites avec rename, mais on peut aussi utiliser l’argument suffix de left_join, qui permet d’indiquer les suffixes à ajouter aux colonnes. Ainsi, on peut faire :

left_join(flights_ex, airports_ex,
  by = c("dest" = "faa"),
  suffix = c("_depart", "_arrivee")
)

On obtient ainsi directement des noms de colonnes nettement plus clairs.

Types de jointures

Jusqu’à présent nous avons utilisé la fonction left_join, mais il existe plusieurs types de jointures.

Partons de deux tables d’exemple, personnes et voitures :

personnes <- tibble(
  nom = c("Sylvie", "Sylvie", "Monique", "Gunter", "Rayan", "Rayan"),
  voiture = c("Twingo", "Ferrari", "Scenic", "Lada", "Twingo", "Clio")
)
nom voiture
Sylvie Twingo
Sylvie Ferrari
Monique Scenic
Gunter Lada
Rayan Twingo
Rayan Clio
voitures <- tibble(
  voiture = c("Twingo", "Ferrari", "Clio", "Lada", "208"),
  vitesse = c("140", "280", "160", "85", "160")
)
voiture vitesse
Twingo 140
Ferrari 280
Clio 160
Lada 85
208 160

left_join

Si on fait un left_join de voitures sur personnes :

left_join(personnes, voitures)
Joining, by = "voiture"
nom voiture vitesse
Sylvie Twingo 140
Sylvie Ferrari 280
Monique Scenic NA
Gunter Lada 85
Rayan Twingo 140
Rayan Clio 160

On voit que chaque ligne de personnes est bien présente, et qu’on lui a ajouté une ligne de voitures correspondante si elle existe. Dans le cas du Scenic, il n’y a avait pas de ligne dans voitures, donc vitesse a été mise à NA. Dans le cas de 208, présente dans voitures mais pas dans personnes, la ligne n’apparaît pas.

Si on fait un left_join cette fois de personnes sur voitures, c’est l’inverse :

left_join(voitures, personnes)
Joining, by = "voiture"
voiture vitesse nom
Twingo 140 Sylvie
Twingo 140 Rayan
Ferrari 280 Sylvie
Clio 160 Rayan
Lada 85 Gunter
208 160 NA

La ligne 208 est là, mais nom est à NA. Par contre Monique est absente. Et on remarquera que la ligne Twingo, présente deux fois dans personnes, a été dupliquée pour être associée aux deux lignes de données de Sylvie et Rayan.

En résumé, quand on fait un left_join(x, y), toutes les lignes de x sont présentes, et dupliquées si nécessaire quand elles apparaissent plusieurs fois dans y. Les lignes de y non présentes dans x disparaissent. Les lignes de x non présentes dans y se voient attribuer des NA pour les nouvelles colonnes.

Intuitivement, on pourrait considérer que left_join(x, y) signifie “ramener l’information de la table y sur la table x”.

En général, left_join sera le type de jointures le plus fréquemment utilisé.

right_join

La jointure right_join est l’exacte symétrique de left_join, c’est-à dire que right_join(x, y) est équivalent à left_join(x,y) :

right_join(personnes, voitures)
Joining, by = "voiture"
nom voiture vitesse
Sylvie Twingo 140
Sylvie Ferrari 280
Gunter Lada 85
Rayan Twingo 140
Rayan Clio 160
NA 208 160

inner_join

Dans le cas de inner_join, seules les lignes présentes à la fois dans x et y sont présentes (et si nécessaire dupliquées) dans la table résultat :

inner_join(personnes, voitures)
Joining, by = "voiture"
nom voiture vitesse
Sylvie Twingo 140
Sylvie Ferrari 280
Gunter Lada 85
Rayan Twingo 140
Rayan Clio 160

Ici la ligne 208 est absente, ainsi que la ligne Monique, qui dans le cas d’un left_join avait été conservée et s’était vue attribuer une vitesse à NA.

full_join

Dans le cas de full_join, toutes les lignes de x et toutes les lignes de y sont conservées (avec des NA ajoutés si nécessaire) même si elles sont absentes de l’autre table :

full_join(personnes, voitures)
Joining, by = "voiture"
nom voiture vitesse
Sylvie Twingo 140
Sylvie Ferrari 280
Monique Scenic NA
Gunter Lada 85
Rayan Twingo 140
Rayan Clio 160
NA 208 160

semi_join et anti_join

semi_join et anti_join sont des jointures filtrantes, c’est-à-dire qu’elles sélectionnent les lignes de x sans ajouter les colonnes de y.

Ainsi, semi_join ne conservera que les lignes de x pour lesquelles une ligne de y existe également, et supprimera les autres. Dans notre exemple, la ligne Monique est donc supprimée :

semi_join(personnes, voitures)
Joining, by = "voiture"
nom voiture
Sylvie Twingo
Sylvie Ferrari
Gunter Lada
Rayan Twingo
Rayan Clio

Un anti_join fait l’inverse, il ne conserve que les lignes de x absentes de y. Dans notre exemple, on ne garde donc que la ligne Monique :

anti_join(personnes, voitures)
Joining, by = "voiture"
nom voiture
Monique Scenic

Jointures avec data.table

data.table fournit une fonction merge beaucoup plus rapide que celle standard de R mais fonctionnant de manière identique.

Ajouter des observations

La fonction rbind, fournie nativement avec R pour ajouter des observations à un tableau, doit être évitée car elle générera des résultats non pertinents si les tableaux que l’on concatènent n’ont pas exactement les mêmes colonnes dans le même ordre.

La fonction bind_rows de dplyr permet d’ajouter des lignes à une table à partir d’une ou plusieurs autres tables.

L’exemple suivant (certes très artificiel) montre l’utilisation de bind_rows. On commence par créer trois tableaux t1, t2 et t3 :

t1 <- airports %>%
  select(faa, name, lat, lon) %>%
  slice(1:2)
t1
t2 <- airports %>%
  select(name, faa, lon, lat) %>%
  slice(5:6)

t2
t3 <- airports %>%
  select(faa, name) %>%
  slice(100:101)
t3

On concaténe ensuite les trois tables avec bind_rows :

bind_rows(t1, t2, t3)

On remarquera que si des colonnes sont manquantes pour certaines tables, comme les colonnes lat et lon de t3, des NA sont automatiquement insérées.

De plus, peu importe l’ordre des variables entre les différentes tables, bind_rows les réassociera en considérant que deux colonnes ayant le même nom dans deux tableaux correspondent à la même variable.

Il peut être utile, quand on concatène des lignes, de garder une trace du tableau d’origine de chacune des lignes dans le tableau final. C’est possible grâce à l’argument .id de bind_rows. On passe à cet argument le nom d’une colonne qui contiendra l’indicateur d’origine des lignes :

bind_rows(t1, t2, t3, .id = "source")

Par défaut la colonne .id ne contient qu’un nombre, différent pour chaque tableau. On peut lui spécifier des valeurs plus explicites en “nommant” les tables dans bind_rows de la manière suivante :

bind_rows(table1 = t1, table2 = t2, table3 = t3, .id = "source")

Une alternative à bind_rows est la fonction rbind.fill de l’extension plyr qui fonctionne de manière similaire.


  1. Si vous me passez l’expression…

Gestion des dates

Si R fournit quelques fonctions natives pour la gestion des dates, l’extension lubridate est recommandée pour tout travail un peu plus fin sur des dates. On pourra se référer :

Fonctions à fenêtre

Ce chapitre est en cours d’écriture.

Ces fonctions sont présentées en détail (en anglais) dans une vignette dédiée de l’extension dplyr (https://cran.r-project.org/web/packages/dplyr/vignettes/window-functions.html).

Manipuler du texte avec stringr

La version originale de ce chapitre a été écrite par Julien Barnier dans le cadre de son Introduction à R et au tidyverse.

Les fonctions de forcats vues précédemment permettent de modifier des modalités d’une variables qualitative globalement. Mais parfois on a besoin de manipuler le contenu même du texte d’une variable de type chaîne de caractères : combiner, rechercher, remplacer…

On va utiliser ici les fonctions de l’extension stringr. Celle-ci fait partie du coeur du tidyverse, elle est donc automatiquement chargée avec :

library(tidyverse)

stringr est en fait une interface simplifiée aux fonctions d’une autre extension, stringi. Si les fonctions de stringr ne sont pas suffisantes ou si on manipule beaucoup de chaînes de caractères, ne pas hésiter à se reporter à la documentation de stringi.

Dans ce qui suit on va utiliser le court tableau d’exemple d suivant :

d <- tibble(
  nom = c("Mr Félicien Machin", "Mme Raymonde Bidule", "M. Martial Truc", "Mme Huguette Chose"),
  adresse = c("3 rue des Fleurs", "47 ave de la Libération", "12 rue du 17 octobre 1961", "221 avenue de la Libération"),
  ville = c("Nouméa", "Marseille", "Vénissieux", "Marseille")
)
nom adresse ville
Mr Félicien Machin 3 rue des Fleurs Nouméa
Mme Raymonde Bidule 47 ave de la Libération Marseille
M. Martial Truc 12 rue du 17 octobre 1961 Vénissieux
Mme Huguette Chose 221 avenue de la Libération Marseille

Expressions régulières

Les fonctions présentées ci-dessous sont pour la plupart prévues pour fonctionner avec des expressions régulières. Celles-ci constituent un mini-langage, qui peut paraître assez cryptique, mais qui est très puissant pour spécifier des motifs de chaînes de caractères.

Elles permettent par exemple de sélectionner le dernier mot avant la fin d’une chaîne, l’ensemble des suites alphanumériques commençant par une majuscule, des nombres de 3 ou 4 chiffres situés en début de chaîne, et beaucoup beaucoup d’autres choses encore bien plus complexes.

Pour donner un exemple concret, l’expression régulière suivante permet de détecter une adresse de courrier électronique1 :

[\w\d+.-_]+@[\w\d.-]+\.[a-zA-Z]{2,}

Par souci de simplicité, dans ce qui suit les exemples seront donnés autant que possible avec de simples chaînes, sans expression régulière. Mais si vous pensez manipuler des données textuelles, il peut être très utile de s’intéresser à cette syntaxe.

Concaténer des chaînes

La première opération de base consiste à concaténer des chaînes de caractères entre elles. On peut le faire avec la fonction paste.

Par exemple, si on veut concaténer l’adresse et la ville :

paste(d$adresse, d$ville)
[1] "3 rue des Fleurs Nouméa"              
[2] "47 ave de la Libération Marseille"    
[3] "12 rue du 17 octobre 1961 Vénissieux" 
[4] "221 avenue de la Libération Marseille"

Par défaut, paste concatène en ajoutant un espace entre les différentes chaînes. On peut spécifier un autre séparateur avec son argument sep :

paste(d$adresse, d$ville, sep = " - ")
[1] "3 rue des Fleurs - Nouméa"              
[2] "47 ave de la Libération - Marseille"    
[3] "12 rue du 17 octobre 1961 - Vénissieux" 
[4] "221 avenue de la Libération - Marseille"

Il existe une variante, paste0, qui concatène sans mettre de séparateur, et qui est légèrement plus rapide :

paste0(d$adresse, d$ville)
[1] "3 rue des FleursNouméa"              
[2] "47 ave de la LibérationMarseille"    
[3] "12 rue du 17 octobre 1961Vénissieux" 
[4] "221 avenue de la LibérationMarseille"

À noter que paste et paste0 sont des fonctions R de base. L’équivalent pour stringr se nomme str_c.

Parfois on cherche à concaténer les différents éléments d’un vecteur non pas avec ceux d’un autre vecteur, comme on l’a fait précédemment, mais entre eux. Dans ce cas paste seule ne fera rien :

paste(d$ville)
[1] "Nouméa"     "Marseille"  "Vénissieux" "Marseille" 

Il faut lui ajouter un argument collapse, avec comme valeur la chaîne à utiliser pour concaténer les éléments :

paste(d$ville, collapse = ", ")
[1] "Nouméa, Marseille, Vénissieux, Marseille"

Convertir en majuscules / minuscules

Les fonctions str_to_lower, str_to_upper et str_to_title permettent respectivement de mettre en minuscules, mettre en majuscules, ou de capitaliser les éléments d’un vecteur de chaînes de caractères :

str_to_lower(d$nom)
[1] "mr félicien machin"  "mme raymonde bidule"
[3] "m. martial truc"     "mme huguette chose" 
str_to_upper(d$nom)
[1] "MR FÉLICIEN MACHIN"  "MME RAYMONDE BIDULE"
[3] "M. MARTIAL TRUC"     "MME HUGUETTE CHOSE" 
str_to_title(d$nom)
[1] "Mr Félicien Machin"  "Mme Raymonde Bidule"
[3] "M. Martial Truc"     "Mme Huguette Chose" 

Découper des chaînes

La fonction str_split permet de “découper” une chaîne de caractère en fonction d’un délimiteur. On passe la chaîne en premier argument, et le délimiteur en second :

str_split("un-deux-trois", "-")
[[1]]
[1] "un"    "deux"  "trois"

On peut appliquer la fonction à un vecteur, dans ce cas le résultat sera une liste :

str_split(d$nom, " ")
[[1]]
[1] "Mr"       "Félicien" "Machin"  

[[2]]
[1] "Mme"      "Raymonde" "Bidule"  

[[3]]
[1] "M."      "Martial" "Truc"   

[[4]]
[1] "Mme"      "Huguette" "Chose"   

Ou un tableau (plus précisément une matrice) si on ajoute simplify = TRUE.

str_split(d$nom, " ", simplify = TRUE)
     [,1]  [,2]       [,3]    
[1,] "Mr"  "Félicien" "Machin"
[2,] "Mme" "Raymonde" "Bidule"
[3,] "M."  "Martial"  "Truc"  
[4,] "Mme" "Huguette" "Chose" 

Si on souhaite créer de nouvelles colonnes dans un tableau de données en découpant une colonne de type texte, on pourra utiliser la fonction separate de l’extension tidyr. Celle-ci est expliquée section @ref(separate).

Voici juste un exemple de son utilisation :

library(tidyr)
d %>% separate(nom, c("genre", "prenom", "nom"))

Extraire des sous-chaînes par position

La fonction str_sub permet d’extraire des sous-chaînes par position, en indiquant simplement les positions des premier et dernier caractères :

str_sub(d$ville, 1, 3)
[1] "Nou" "Mar" "Vén" "Mar"

Détecter des motifs

str_detect permet de détecter la présence d’un motif parmi les élements d’un vecteur. Par exemple, si on souhaite identifier toutes les adresses contenant Libération :

str_detect(d$adresse, "Libération")
[1] FALSE  TRUE FALSE  TRUE

str_detect renvoit un vecteur de valeurs logiques et peut donc être utilisée, par exemple, avec le verbe filter de dplyr pour extraire des sous-populations.

Une variante, str_count, compte le nombre d’occurrences d’une chaîne pour chaque élément d’un vecteur :

str_count(d$ville, "s")
[1] 0 1 2 1

Attention, les fonctions de stringr étant prévues pour fonctionner avec des expressions régulières, certains caractères n’auront pas le sens habituel dans la chaîne indiquant le motif à rechercher. Par exemple, le . ne sera pas un point mais le symbole représentant n’importe quel caractère.

La section sur les modificateurs de motifs explique comment utiliser des chaîne classiques au lieu d’expressions régulières.

On peut aussi utiliser str_subset pour ne garder d’un vecteur que les éléments correspondant au motif :

str_subset(d$adresse, "Libération")
[1] "47 ave de la Libération"    
[2] "221 avenue de la Libération"

Extraire des motifs

str_extract permet d’extraire les valeurs correspondant à un motif. Si on lui passe comme motif une chaîne de caractère, cela aura peu d’intérêt :

str_extract(d$adresse, "Libération")
[1] NA           "Libération" NA           "Libération"

C’est tout de suite plus intéressant si on utilise des expressions régulières. Par exemple la commande suivante permet d’isoler les numéros de rue.

str_extract(d$adresse, "^\\d+")
[1] "3"   "47"  "12"  "221"

str_extract ne récupère que la première occurrence du motif. Si on veut toutes les extraire on peut utiliser str_extract_all. Ainsi, si on veut extraire l’ensemble des nombres présents dans les adresses :

str_extract_all(d$adresse, "\\d+")
[[1]]
[1] "3"

[[2]]
[1] "47"

[[3]]
[1] "12"   "17"   "1961"

[[4]]
[1] "221"

Si on veut faire de l’extraction de groupes dans des expressions régulières (identifiés avec des parenthèses), on pourra utiliser str_match.

À noter que si on souhaite extraire des valeurs d’une colonne texte d’un tableau de données pour créer de nouvelles variables, on pourra utiliser la fonction extract de l’extension tidyr, décrite plus haut.

Par exemple :

library(tidyr)
d %>% extract(adresse, "type_rue", "^\\d+ (.*?) ", remove = FALSE)

Remplacer des motifs

La fonction str_replace permet de remplacer une chaîne ou un motif par une autre.

Par exemple, on peut remplace les occurrence de “Mr” par “M.” dans les noms de notre tableau :

str_replace(d$nom, "Mr", "M.")
[1] "M. Félicien Machin"  "Mme Raymonde Bidule"
[3] "M. Martial Truc"     "Mme Huguette Chose" 

La variante str_replace_all permet de spécifier plusieurs remplacements d’un coup :

str_replace_all(d$adresse, c("avenue" = "Avenue", "ave" = "Avenue", "rue" = "Rue"))
[1] "3 Rue des Fleurs"           
[2] "47 Avenue de la Libération" 
[3] "12 Rue du 17 octobre 1961"  
[4] "221 Avenue de la Libération"

Modificateurs de motifs

Par défaut, les motifs passés aux fonctions comme str_detect, str_extract ou str_replace sont des expressions régulières classiques.

On peut spécifier qu’un motif n’est pas une expression régulière mais une chaîne de caractères normale en lui appliquant la fonction fixed. Par exemple, si on veut compter le nombre de points dans les noms de notre tableau, le paramétrage par défaut ne fonctionnera pas car dans une expression régulière le . est un symbole signifiant “n’importe quel caractère” :

str_count(d$nom, ".")
[1] 18 19 15 18

Il faut donc spécifier que notre point est bien un point avec fixed :

str_count(d$nom, fixed("."))
[1] 0 0 1 0

On peut aussi modifier le comportement des expressions régulières à l’aide de la fonction regex. On peut ainsi rendre les motifs insensibles à la casse avec ignore_case :

str_detect(d$nom, "mme")
[1] FALSE FALSE FALSE FALSE
str_detect(d$nom, regex("mme", ignore_case = TRUE))
[1] FALSE  TRUE FALSE  TRUE

On peut également permettre aux regex d’être multilignes avec l’option multiline = TRUE, etc.

Insérer une variable dans une chaîne de caractères

La fonction str_glue repose sur l’extension glue. Elle permet, à l’aide d’une syntaxe un peu spécifique, de pouvoir insérer facilement les valeurs d’une ou plusieurs variables dans une chaîne de caractères. Prenons un exemple :

prenom <- "Fred"
age <- 28
anniversaire <- as.Date("1991-10-12")
str_glue(
  "Je m'appelle {prenom}. ",
  "L'année prochaine j'aurai {age + 1} ans, ",
  "car je suis né le {format(anniversaire, '%A %d %B %Y')}."
)
Je m'appelle Fred. L'année prochaine j'aurai 29 ans, car je suis né le samedi 12 octobre 1991.

Sa variante str_glue_data est adaptée lorsque l’on travaille sur un tableau de données avec dplyr.

d %>% mutate(phrase = str_glue_data(d, "{nom} habite à {ville}."))

Ressources

L’ouvrage R for Data Science, accessible en ligne, contient un chapitre entier sur les chaînes de caractères et les expressions régulières (en anglais).

Le site officiel de stringr contient une liste des fonctions et les pages d’aide associées, ainsi qu’un article dédié aux expressions régulières.

Pour des besoins plus pointus, on pourra aussi utiliser l’extension stringi sur laquelle est elle-même basée stringr.


  1. Il s’agit en fait d’une version très simplifiée, la véritable expression permettant de tester si une adresse mail est valide fait plus de 80 lignes…

Réorganiser ses données avec tidyr

La version originale de ce chapitre a été écrite par Julien Barnier dans le cadre de son Introduction à R et au tidyverse.

Tidy data

Comme indiqué dans l’introduction au tidyverse, les extensions du tidyverse comme dplyr ou ggplot2 partent du principe que les données sont “bien rangées” sous forme de tidy data.

Prenons un exemple avec les données suivantes, qui indique la population de trois pays pour quatre années différentes :

country 1992 1997 2002 2007
Belgium 10045622 10199787 10311970 10392226
France 57374179 58623428 59925035 61083916
Germany 80597764 82011073 82350671 82400996

Imaginons qu’on souhaite représenter avec ggplot2 l’évolution de la population pour chaque pays sous forme de lignes : c’est impossible avec les données sous ce format. On a besoin d’arranger le tableau de la manière suivante :

country annee population
Belgium 1992 10045622
France 1992 57374179
Germany 1992 80597764
Belgium 1997 10199787
France 1997 58623428
Germany 1997 82011073
Belgium 2002 10311970
France 2002 59925035
Germany 2002 82350671
Belgium 2007 10392226
France 2007 61083916
Germany 2007 82400996

C’est seulement avec les données dans ce format qu’on peut réaliser le graphique :

ggplot(d) +
  geom_line(aes(x = annee, y = population, color = country)) +
  scale_x_continuous(breaks = unique(d$annee))

C’est la même chose pour dplyr, par exemple si on voulait calculer la population minimale pour chaque pays avec summarise :

d %>%
  group_by(country) %>%
  summarise(pop_min = min(population))
`summarise()` ungrouping output (override with `.groups` argument)
# A tibble: 3 x 2
  country  pop_min
  <fct>      <int>
1 Belgium 10045622
2 France  57374179
3 Germany 80597764

Trois règles pour des données bien rangées

Le concept de tidy data repose sur trois règles interdépendantes. Des données sont considérées comme tidy si :

  1. chaque ligne correspond à une observation
  2. chaque colonne correspond à une variable
  3. chaque valeur est présente dans une unique case de la table ou, de manière équivalente, si des unités d’observations différentes sont présentes dans des tables différentes

Ces règles ne sont pas forcément très intuitives. De plus, il y a une infinité de manières pour un tableau de données de ne pas être tidy.

Prenons par exemple les règles 1 et 2 et le tableau de notre premier exemple :

country 1992 1997 2002 2007
Belgium 10045622 10199787 10311970 10392226
France 57374179 58623428 59925035 61083916
Germany 80597764 82011073 82350671 82400996

Pourquoi ce tableau n’est pas tidy ? Parce que si on essaie d’identifier les variables mesurées dans le tableau, il y en a trois : le pays, l’année et la population. Or elles ne correspondent pas aux colonnes de la table. C’est le cas par contre pour la table transformée :

country annee population
Belgium 1992 10045622
France 1992 57374179
Germany 1992 80597764
Belgium 1997 10199787
France 1997 58623428
Germany 1997 82011073
Belgium 2002 10311970
France 2002 59925035
Germany 2002 82350671
Belgium 2007 10392226
France 2007 61083916
Germany 2007 82400996

On peut remarquer qu’en modifiant notre table pour satisfaire à la deuxième règle, on a aussi réglé la première : chaque ligne correspond désormais à une observation, en l’occurrence l’observation de trois pays à plusieurs moments dans le temps. Dans notre table d’origine, chaque ligne comportait en réalité quatre observations différentes.

Ce point permet d’illustrer le fait que les règles sont interdépendantes.

Autre exemple, généré depuis le jeu de données nycflights13, permettant cette fois d’illustrer la troisième règle :

year month day dep_time carrier name flights_per_year
2013 1 1 517 UA United Air Lines Inc. 58665
2013 1 1 533 UA United Air Lines Inc. 58665
2013 1 1 542 AA American Airlines Inc. 32729
2013 1 1 554 UA United Air Lines Inc. 58665
2013 1 1 558 AA American Airlines Inc. 32729
2013 1 1 558 UA United Air Lines Inc. 58665
2013 1 1 558 UA United Air Lines Inc. 58665
2013 1 1 559 AA American Airlines Inc. 32729

Dans ce tableau on a bien une observation par ligne (un vol), et une variable par colonne. Mais on a une “infraction” à la troisième règle, qui est que chaque valeur doit être présente dans une unique case : si on regarde la colonne name, on a en effet une duplication de l’information concernant le nom des compagnies aériennes. Notre tableau mêle en fait deux types d’observations différents : des observations sur les vols, et des observations sur les compagnies aériennes.

Pour “arranger” ce tableau, il faut séparer les deux types d’observations en deux tables différentes :

year month day dep_time carrier
2013 1 1 517 UA
2013 1 1 533 UA
2013 1 1 542 AA
2013 1 1 554 UA
2013 1 1 558 AA
2013 1 1 558 UA
2013 1 1 558 UA
2013 1 1 559 AA
carrier name flights_per_year
UA United Air Lines Inc. 58665
AA American Airlines Inc. 32729

On a désormais deux tables distinctes, l’information n’est pas dupliquée, et on peut facilement faire une jointure si on a besoin de récupérer l’information d’une table dans une autre.

Les verbes de tidyr

L’objectif de tidyr est de fournir des fonctions pour arranger ses données et les convertir dans un format tidy. Ces fonctions prennent la forme de verbes qui viennent compléter ceux de dplyr et s’intègrent parfaitement dans les séries de pipes (%>%), les pipelines, permettant d’enchaîner les opérations.

pivot_longer : rassembler des colonnes

Prenons le tableau d suivant, qui liste la population de 6 pays en 2002 et 2007 :

country 2002 2007
Belgium 10311970 10392226
France 59925035 61083916
Germany 82350671 82400996
Italy 57926999 58147733
Spain 40152517 40448191
Switzerland 7361757 7554661

Dans ce tableau, une même variable (la population) est répartie sur plusieurs colonnes, chacune représentant une observation à un moment différent. On souhaite que la variable ne représente plus qu’une seule colonne, et que les observations soient réparties sur plusieurs lignes.

Pour cela on va utiliser la fonction pivot_longer1 :

d %>% pivot_longer(cols = c(`2002`, `2007`), names_to = "annee", values_to = "population")
# A tibble: 12 x 3
   country     annee population
   <fct>       <chr>      <int>
 1 Belgium     2002    10311970
 2 Belgium     2007    10392226
 3 France      2002    59925035
 4 France      2007    61083916
 5 Germany     2002    82350671
 6 Germany     2007    82400996
 7 Italy       2002    57926999
 8 Italy       2007    58147733
 9 Spain       2002    40152517
10 Spain       2007    40448191
11 Switzerland 2002     7361757
12 Switzerland 2007     7554661

La fonction pivot_longer prend comme arguments la liste des colonnes à rassembler (on peut également y utiliser les différentes fonctions de sélection de variables utilisables avec select, voir select_helpers), ainsi que deux arguments names_to et values_to :

  • names_to est le nom de la colonne qui va contenir les “noms” des colonnes originelles, c’est-à-dire les identifiants des différentes observations
  • values_to est le nom de la colonne qui va contenir la valeur des observations

Parfois il est plus rapide d’indiquer à pivot_longer les colonnes qu’on ne souhaite pas rassembler. On peut le faire avec la syntaxe suivante :

d %>% pivot_longer(-country, names_to = "annee", values_to = "population")
# A tibble: 12 x 3
   country     annee population
   <fct>       <chr>      <int>
 1 Belgium     2002    10311970
 2 Belgium     2007    10392226
 3 France      2002    59925035
 4 France      2007    61083916
 5 Germany     2002    82350671
 6 Germany     2007    82400996
 7 Italy       2002    57926999
 8 Italy       2007    58147733
 9 Spain       2002    40152517
10 Spain       2007    40448191
11 Switzerland 2002     7361757
12 Switzerland 2007     7554661

pivot_wider : disperser des lignes

La fonction pivot_wider2 est l’inverse de pivot_longer.

Soit le tableau d suivant :

country continent year variable value
Belgium Europe 2002 lifeExp 78.320
Belgium Europe 2007 lifeExp 79.441
France Europe 2002 lifeExp 79.590
France Europe 2007 lifeExp 80.657
Germany Europe 2002 lifeExp 78.670
Germany Europe 2007 lifeExp 79.406
Belgium Europe 2002 pop 10311970.000
Belgium Europe 2007 pop 10392226.000
France Europe 2002 pop 59925035.000
France Europe 2007 pop 61083916.000
Germany Europe 2002 pop 82350671.000
Germany Europe 2007 pop 82400996.000

Ce tableau a le problème inverse du précédent : on a deux variables, lifeExp et pop qui, plutôt que d’être réparties en deux colonnes, sont réparties entre plusieurs lignes.

On va donc utiliser pivot_wider pour disperser ces lignes dans deux colonnes différentes :

d %>% pivot_wider(names_from = variable, values_from = value)
# A tibble: 6 x 5
  country continent  year lifeExp      pop
  <fct>   <fct>     <int>   <dbl>    <dbl>
1 Belgium Europe     2002    78.3 10311970
2 Belgium Europe     2007    79.4 10392226
3 France  Europe     2002    79.6 59925035
4 France  Europe     2007    80.7 61083916
5 Germany Europe     2002    78.7 82350671
6 Germany Europe     2007    79.4 82400996

pivot_wider prend deux arguments principaux :

  • names_from indique la colonne contenant les noms des nouvelles variables à créer
  • values_from indique la colonne contenant les valeurs de ces variables

Il peut arriver que certaines variables soient absentes pour certaines observations. Dans ce cas l’argument values_fill permet de spécifier la valeur à utiliser pour ces données manquantes (par défaut, les valauers manquantes sont indiquées avec NA).

Exemple avec le tableau d suivant :

country continent year variable value
Belgium Europe 2002 lifeExp 78.320
Belgium Europe 2007 lifeExp 79.441
France Europe 2002 lifeExp 79.590
France Europe 2007 lifeExp 80.657
Germany Europe 2002 lifeExp 78.670
Germany Europe 2007 lifeExp 79.406
Belgium Europe 2002 pop 10311970.000
Belgium Europe 2007 pop 10392226.000
France Europe 2002 pop 59925035.000
France Europe 2007 pop 61083916.000
Germany Europe 2002 pop 82350671.000
Germany Europe 2007 pop 82400996.000
France Europe 2002 density 94.000
d %>%
  pivot_wider(names_from = variable, values_from = value)
# A tibble: 6 x 6
  country continent  year lifeExp      pop density
  <chr>   <chr>     <dbl>   <dbl>    <dbl>   <dbl>
1 Belgium Europe     2002    78.3 10311970      NA
2 Belgium Europe     2007    79.4 10392226      NA
3 France  Europe     2002    79.6 59925035      94
4 France  Europe     2007    80.7 61083916      NA
5 Germany Europe     2002    78.7 82350671      NA
6 Germany Europe     2007    79.4 82400996      NA
d %>%
  pivot_wider(names_from = variable, values_from = value, values_fill = list(value = 0))
# A tibble: 6 x 6
  country continent  year lifeExp      pop density
  <chr>   <chr>     <dbl>   <dbl>    <dbl>   <dbl>
1 Belgium Europe     2002    78.3 10311970       0
2 Belgium Europe     2007    79.4 10392226       0
3 France  Europe     2002    79.6 59925035      94
4 France  Europe     2007    80.7 61083916       0
5 Germany Europe     2002    78.7 82350671       0
6 Germany Europe     2007    79.4 82400996       0

separate : séparer une colonne en plusieurs

Parfois on a plusieurs informations réunies en une seule colonne et on souhaite les séparer. Soit le tableau d’exemple caricatural suivant, nommé df :

eleve note
Félicien Machin 5/20
Raymonde Bidule 6/10
Martial Truc 87/100

separate permet de séparer la colonne note en deux nouvelles colonnes note et note_sur :

df %>% separate(note, c("note", "note_sur"))
# A tibble: 3 x 3
  eleve           note  note_sur
  <chr>           <chr> <chr>   
1 Félicien Machin 5     20      
2 Raymonde Bidule 6     10      
3 Martial Truc    87    100     

separate prend deux arguments principaux, le nom de la colonne à séparer et un vecteur indiquant les noms des nouvelles variables à créer. Par défaut separate sépare au niveau des caractères non-alphanumérique (espace, symbole, etc.). On peut lui indiquer explicitement le caractère sur lequel séparer avec l’argument sep :

df %>% separate(eleve, c("prenom", "nom"), sep = " ")
# A tibble: 3 x 3
  prenom   nom    note  
  <chr>    <chr>  <chr> 
1 Félicien Machin 5/20  
2 Raymonde Bidule 6/10  
3 Martial  Truc   87/100

unite : regrouper plusieurs colonnes en une seule

unite est l’opération inverse de separate. Elle permet de regrouper plusieurs colonnes en une seule. Imaginons qu’on obtient le tableau d suivant :

code_departement code_commune commune pop_tot
01 004 Ambérieu-en-Bugey 14233
01 007 Ambronay 2437
01 014 Arbent 3440
01 024 Attignat 3110
01 025 Bâgé-la-Ville 3130
01 027 Balan 2785

On souhaite reconstruire une colonne code_insee qui indique le code INSEE de la commune, et qui s’obtient en concaténant le code du département et celui de la commune. On peut utiliser unite pour cela :

d %>% unite(code_insee, code_departement, code_commune)
# A tibble: 6 x 3
  code_insee commune           pop_tot
  <chr>      <chr>               <int>
1 01_004     Ambérieu-en-Bugey   14233
2 01_007     Ambronay             2437
3 01_014     Arbent               3440
4 01_024     Attignat             3110
5 01_025     Bâgé-la-Ville        3130
6 01_027     Balan                2785

Le résultat n’est pas idéal : par défaut unite ajoute un caractère _ entre les deux valeurs concaténées, alors qu’on ne veut aucun séparateur. De plus, on souhaite conserver nos deux colonnes d’origine, qui peuvent nous être utiles. On peut résoudre ces deux problèmes à l’aide des arguments sep et remove :

d %>%
  unite(code_insee, code_departement, code_commune,
    sep = "", remove = FALSE
  )
# A tibble: 6 x 5
  code_insee code_departement code_commune commune   pop_tot
  <chr>      <chr>            <chr>        <chr>       <int>
1 01004      01               004          Ambérieu~   14233
2 01007      01               007          Ambronay     2437
3 01014      01               014          Arbent       3440
4 01024      01               024          Attignat     3110
5 01025      01               025          Bâgé-la-~    3130
6 01027      01               027          Balan        2785

extract : créer de nouvelles colonnes à partir d’une colonne de texte

extract permet de créer de nouvelles colonnes à partir de sous-chaînes d’une colonne de texte existante, identifiées par des groupes dans une expression régulière.

Par exemple, à partir du tableau suivant :

eleve note
Félicien Machin 5/20
Raymonde Bidule 6/10
Martial Truc 87/100

On peut extraire les noms et prénoms dans deux nouvelles colonnes avec :

df %>% extract(
  eleve,
  c("prenom", "nom"),
  "^(.*) (.*)$"
)

On passe donc à extract trois arguments : la colonne d’où on doit extraire les valeurs, un vecteur avec les noms des nouvelles colonnes à créer, et une expression régulière comportant autant de groupes (identifiés par des parenthèses) que de nouvelles colonnes.

Par défaut la colonne d’origine n’est pas conservée dans la table résultat. On peut modifier ce comportement avec l’argument remove = FALSE. Ainsi, le code suivant extrait les initiales du prénom et du nom mais conserve la colonne d’origine :

df %>% extract(eleve,
  c("initiale_prenom", "initiale_nom"),
  "^(.).* (.).*$",
  remove = FALSE
)

complete : compléter des combinaisons de variables manquantes

Imaginons qu’on ait le tableau de résultats suivants :

eleve matiere note
Alain Maths 16
Alain Français 9
Barnabé Maths 17
Chantal Français 11

Les élèves Barnabé et Chantal n’ont pas de notes dans toutes les matières. Supposons que c’est parce qu’ils étaient absents et que leur note est en fait un 0. Si on veut calculer les moyennes des élèves, on doit compléter ces notes manquantes.

La fonction complete est prévue pour ce cas de figure : elle permet de compléter des combinaisons manquantes de valeurs de plusieurs colonnes.

On peut l’utiliser de cette manière :

df %>% complete(eleve, matiere)

On voit que les combinaisons manquante “Barnabé - Français” et “Chantal - Maths” ont bien été ajoutées par complete.

Par défaut les lignes insérées récupèrent des valeurs manquantes NA pour les colonnes restantes. On peut néanmoins choisir une autre valeur avec l’argument fill, qui prend la forme d’une liste nommée :

df %>% complete(eleve, matiere, fill = list(note = 0))

Parfois on ne souhaite pas inclure toutes les colonnes dans le calcul des combinaisons de valeurs. Par exemple, supposons qu’on rajoute dans notre tableau une colonne avec les identifiants de chaque élève :

id eleve matiere note
1001001 Alain Maths 16
1001001 Alain Français 9
1001002 Barnabé Maths 17
1001003 Chantal Français 11

Si on applique complete comme précédemment, le résultat n’est pas bon car il contient toutes les combinaisons de id, eleve et matiere.

df %>% complete(id, eleve, matiere)

Dans ce cas, pour signifier à complete que id et eleve sont deux attributs d’un même individu et ne doivent pas être combinés entre eux, on doit les placer dans une fonction nesting :

df %>% complete(nesting(id, eleve), matiere)

Ressources

Chaque jeu de données est différent, et le travail de remise en forme est souvent long et plus ou moins compliqué. On n’a donné ici que les exemples les plus simples, et c’est souvent en combinant différentes opérations qu’on finit par obtenir le résultat souhaité.

Le livre R for data science, librement accessible en ligne, contient un chapitre complet sur la remise en forme des données.

L’article Tidy data, publié en 2014 dans le Journal of Statistical Software, présente de manière détaillée le concept éponyme (mais il utilise des extensions désormais obsolètes qui ont depuis été remplacées par dplyr ettidyr).

Le site de l’extension est accessible à l’adresse : http://tidyr.tidyverse.org/ et contient une liste des fonctions et les pages d’aide associées.

En particulier, on pourra se référer à la vignette dédiée à pivot_wider et pivot_longer pour des exemples avancés de réorganisation des données.

Pour des usages avancés, il est possible avec tidyr de gérer des données nichées (nested data), c’est-à-dire des tableaux de données dans des tableaux de données. Ces fonctionnalités, réservées aux utilisateurs avancés, sont décrites dans une vignette spécifique.

Fichiers volumineux

Si l’on a des tableaux de données particulièrement volumineux (plusieurs Go), les fonctions de tidyr ne sont pas forcéments les plus performantes.

On aura alors intérêt à regarder du côté des fonctions melt et dcast de l’extension data.table développées pour optimiser la performance sur les grands tableaux de données.

Pour plus de détails, voir la vignette dédiée : https://rdatatable.gitlab.io/data.table/articles/datatable-reshape.html


  1. pivot_longer est une version plus récente et plus robuste de la fonction gather.

  2. pivot_wider est une version plus récente et plus robuste de la fonction spread.

Scraping

Une grande partie des données que l’on trouve sur Internet n’y sont pas présentées sous la forme d’un jeu de données : dans de très nombreux cas de figure, ces données peuvent être présentées, par exemple, sous la forme d’un tableau, ou d’une série de pages Web. Ce chapitre explique comment récupérer ces données, de manière à en permettre la manipulation dans R.

La récupération de données numériques, que l’on va illustrer à partir de trois sites Internet consacrés aux théories du complot circulant en France, est plus connue sous le nom de scraping ou de Web scraping. Il s’agit d’un ensemble de techniques, dont on présentera ici que les principaux aspects, appliqués à un cas d’étude précis.

Les sources de l’exemple

Ce chapitre s’intéresse à trois sites Internet consacrés aux théories du complot et à leurs diffuseurs, les « conspirationnistes ». Le site de Rudy Reichstadt, Conspiracy Watch, qui va devenir notre principale source de données, propose une définition de ce terme. La seconde source utilisée, le site Confusionnisme d’Ornella Guyet, utilise une définition différente, qui recoupe largement la première du point de vue des individus et des groupes qu’elle identifie. Notre troisième source, le site anonyme Conspis hors de nos vi[ll]es, ne propose pas de définition précise pour sa part, mais fournit quelques éléments supplémentaires de description.

Les termes de « théorie du complot » et de « conspirationnisme » étant difficiles à saisir en seulement quelques phrases, on renverra le lecteur à la note publiée par Rudy Reichstadt pour l’Observatoire des radicalités politiques de la Fondation Jean Jaurès. Cette note donne un bon aperçu des différents groupes impliqués dans la diffusion de ces « théories » en France, que l’on retrouve dans une cartographie en réseau de leurs sites Internet, réalisée par Joël Gombin en juillet 2014. Les données récupérées dans ce chapitre recoupent les informations fournies dans ces deux sources.

Les blogs

Les sites Internet auxquels on s’intéresse sont tous les trois publiés sous la forme de blogs. Ce détail est important, car pour en récupérer les informations publiées par ces sites, il va falloir comprendre la structure sous-jacente de ces blogs, c’est-à-dire la syntaxe HTML de leurs pages. Les sites Confusionnisme et Conspis hors de nos vi[ll]es sont les plus simples à comprendre. En effet, ils sont tous les deux publiés grâce au moteur de blog WordPress, qui permet de parcourir les différentes pages d’un blog en rajoutant le suffixe /page/n à l’adresse-racine du site, de la manière suivante :

http://confusionnisme.info/page/1
http://confusionnisme.info/page/2
http://confusionnisme.info/page/3
...
http://conspishorsdenosvies.noblogs.org/page/1
http://conspishorsdenosvies.noblogs.org/page/2
http://conspishorsdenosvies.noblogs.org/page/3
...

En navigant ces liens, on s’aperçoit que les deux sites en question n’ont publié qu’un nombre limité de billets : il n’y a que 4 pages de billets sur le premier, et 5 pages sur le second. Le site Conspiracy Watch est, en comparaison, beaucoup plus riche : en effet, comme l’indique le compteur visible en bas de chaque page, le site compte 60 pages de billets, auxquelles le lecteur peut accéder en utilisant un suffixe différent, lié à l’utilisation d’un moteur de blog différent de WordPress. Dans ce cas de figure, le suffixe ne renvoie pas à une « page », mais à un « compteur » de billets, où le dernier billet publié est numéroté 0 :

http://www.conspiracywatch.info/?start=0
http://www.conspiracywatch.info/?start=20
http://www.conspiracywatch.info/?start=40
...

Suivant ce schéma de pagination, qui commence à 0 puis augmente de 20 billets par page, la page 60 va correspondre au suffixe ?start=1180. On connaît donc désormais le nombres de pages à récupérer sur chacun des blogs étudiés, en notant bien que c’est le site Conspiracy Watch qui va fournir la très grande majorité des pages. On aurait pu « découvrir » ces informations de manière programmatique, en écrivant un peu de code pour ce faire, mais un repérage manuel du nombre de pages sur chacun des blogs est ici tout aussi rapide, même s’il faudra le mettre à jour lorsque les blogs auront publié de nouvelles pages de billets.

Les mots-clés

Sur chacun des blogs auxquels on s’intéresse, on trouve des billets très détaillés sur tel ou tel groupe diffusant une ou plusieurs « théories du complot ». Sur les blogs Confusionnisme et Conspiracy Watch, on trouve par exemple deux articles sur un groupuscule ayant appelé à un « Mouvement du 14 juillet » 2015. Sur le blog Conspis hors de nos vi[ll]es, qui a cessé de publier en mars 2012, le dernier billet évoque un autre exemple de ces groupes. Ces différents billets sont tous soigneusement catégorisés par de très nombreux mots-clés, qui incluent notamment les noms propres des individus cités ; ce billet, par exemple, se termine par les mots-clés suivants :

11 septembre, antiaméricanisme, apollo 11, etat islamique, etats-unis, laurent louis, lune

Ces mots-clés sont destinés à permettre aux lecteurs de naviguer plus facilement à travers les différents billets du site, ainsi qu’à faciliter l’indexation du blog par les moteurs de recherche. Ce que l’on se propose de faire ici consiste à récupérer, pour chacun des billets publiés par chacun des trois blogs, l’ensemble de ces mots-clés, ainsi que les titres, les dates de publication et les adresses Internet – les URL – des billets auxquels ils correspondent. Ces données permettront par la suite de construire un réseau de co-occcurrences de ces mots-clés, c’est-à-dire une représentation graphique des associations entre ces mots-clés sur la base des trois sources utilisées.

Récupération des données

Pour récupérer les données des trois blogs, on va commencer par charger quelques extensions utilisées dans plusieurs autres chapitres : l’extension dplyr va servir à manipuler les données au fur et à mesure de leur récupération ; l’extension readr va servir à sauvegarder le résultat final au format CSV ; l’extension lubridate va servir à convertir les dates de publication des billets vers un même format générique ; et l’extension stringr va servir à nettoyer le texte récupéré.

library(dplyr)
library(readr)
library(lubridate)
library(stringr)

Chargeons à présent l’extension rvest, qui va fournir les fonctions essentielles à la récupération des données de chacun des blogs. Comme l’explique l’auteur de l’extension, celle-ci est inspirée d’extensions équivalentes disponibles pour le langage Python. Sa fonctionnalité principale est de permettre à l’utilisateur, à l’aide d’une syntaxe simplifiée ou à l’aide de la syntaxe XPath, de sélectionner les différents éléments d’une page Web, à partir des balises HTML et CSS de cette page.1

library(rvest)

Récupération d’éléments HTML

Commençons par le blog Confusionnisme. Un rapide coup d’oeil au code source de sa page d’accueil montre que les billets publiés sur ce blog se trouvent dans une suite de structures : l’une d’entre elles, <div id="scraping_content">, qui se lit « diviseur à identifiant content », contient tous les billets, et à l’intérieur de cette structure, tous les titres de billets se trouvent dans un hyperlien <a> à l’intérieur d’une balise <h1 class="entry-title">, qui se lit « titre de niveau 1 de classe « entry-title ».

Récupérons désormais le code source de la page d’accueil du blog grâce à la fonction html. Une fois exécuté le code ci-dessous, affichez le contenu de l’objet h pour réaliser que vous venez de récupérer le code source HTML de la page d’accueil du blog :

h <- html("http://confusionnisme.info/")

Sélectionnons, à présent, toutes les balises correspondant aux identifiants notés ci-dessus, grâce à la fonction html_nodes. Pour gagner de la place, on n’affichera ici que les deux premiers titres de billets que renvoie cette dernière fonction :

html_nodes(h, "#content .entry-title a") %>%
  head(2)

Le code ci-dessus signifie : « sélectionner tous les hyperliens <a>, à l’intérieur des éléments identifiés par la classe entry-title, à l’intérieur de l’élément portant l’identifiant content ». Comme l’on peut le voir, les identifiants des éléments HTML (id), qui sont censés être uniques, sont codés par un dièse (#), et les classes de ces mêmes éléments (class), qui peuvent se répéter, sont codées par un point (.). Ces codes sont identiques à ceux que l’on utilise pour attribuer des styles particuliers à ces éléments en langage CSS.

Les éléments HTML que l’on a sélectionnés contiennent aussi bien des balises HTML (telles que <a> et <i>) que du texte. Pour ne sélectionner que le texte, on rajoute la fonction html_text au code montré ci-dessus. Toujours par économie de place, on ne montre que les deux premiers résultats de ce nouvel enchaînement de fonctions :

html_nodes(h, "#content .entry-title a") %>%
  html_text %>%
  head(2)

Voilà qui permet donc de récupérer les titres des billets ! Pour récupérer les hyperliens vers ces billets, rien de plus simple : au lieu de récupérer le texte des titres, il suffit de demander à récupérer l’attribut href de chaque lien, en utilisant la fonction html_attr. On obtient cette fois-ci les hyperliens complets vers chaque billet :

html_nodes(h, "#content .entry-title a") %>%
  html_attr("href") %>%
  head(2)

Présentons encore un exemple de sélection d’éléments sur la page d’accueil de ce blog, cette fois-ci en montrant l’intégralité des éléments récupérés, car ils prennent peu de place à l’écran. Ici, on récupère les dates de publications des billets, qui se trouvent, toujours selon le code source de la page, dans une balise <time> qui se trouve dans une balise <header class="entry-meta">. Le code que l’on donne à la fonction html_nodes est donc :

html_nodes(h, "#content header.entry-header time") %>%
  html_text

On voit bien ici que les deux premières dates sont identiques aux dates qui figurent dans les hyperliens des deux premiers billets, tels que vus plus haut.

html_nodes(h, "#content header.entry-header time") %>%
  html_text

Terminons, enfin, par un exemple plus compliqué. Comme on l’a déjà écrit, chacun des billets du blog est accompagné de plusieurs mots-clés. Après inspection du code source, on voit que ces mots-clés se trouvent regroupés dans un élément appelé <span class="tag-links">. Visionnons les deux premiers éléments en question, toujours à l’aide de la même syntaxe de sélection :

html_nodes(h, ".tag-links") %>%
    head(2)

Pour pouvoir stocker tous les mots-clés d’un billet sur la même ligne d’un fichier CSV, qui contiendra aussi le titre du billet, son hyperlien et sa date de publication, il va falloir regroupr ces mots-clés. On va donc, à l’intérieur de chacun des éléments de la liste d’éléments <span>, extraire le texte des mots-clés, contenus dans les éléments <a>, et les “coller” ensemble grâce à la fonction paste0 et à son argument collapse :

html_nodes(h, ".tag-links") %>%
  sapply(function(x) html_nodes(x, "a") %>%
           html_text %>%
           paste0(collapse = ";")) %>%
  head(2)

L’astuce se trouve ici dans l’utilisation de la fonction sapply, qui permet de travailler sur chacun des éléments <span class="tag-links"> de manière séparée. L’utilisation de la fonction pipe %>% a par ailleurs permis de travailler de manière cumulative, par essai-erreur, tout en produisant un code final plutôt lisible.

Récupération de plusieurs pages

On sait désormais comment récupérer les informations que l’on veut collecter. Le blog Confusionnisme n’ayant que 4 pages, il va être très simple de les récupérer à l’aide d’une petite boucle qui récupère chaque page, en extrait les données inspectées ci-dessus, et les rajoute à un jeu de données initialement vide, nommé d1, grâce à la fonction rbind :

d1 = data_frame()

for(i in 1:4) {
  
  h = html(paste0("http://confusionnisme.info/page/", i))
  
  d1 = rbind(d1, data_frame(
    url = html_nodes(h, "#content .entry-title a") %>% html_attr("href"),
    title = html_nodes(h, "#content .entry-title a") %>% html_text,
    date = html_nodes(h, "#content header.entry-header time") %>% html_text,
    tags = html_nodes(h, ".tag-links") %>%
      sapply(function(x) html_nodes(x, "a") %>%
               html_text %>%
               paste0(collapse = ";"))
  ))
  
}

À la date de publication de ce blog, ce petit bout de code récupère les 36 billets étalés sur les 4 pages du site Confusionnisme. Comme le montre l’inspection du résultat, le jeu de données que l’on vient de constituer contient l’adresse, le titre, la date de publication et les mots-clés de ces billets :

View(d1)

Il ne reste plus qu’à convertir la variable date vers le format générique yyyy-mm-dd que propose R à travers la fonction as.Date. Pour convertir la variable, on utilise l’extension lubridate, qui peut facilement interpréter les mois écrits en langue française grâce à l’argument locale spécifié ci-dessous :

d1$date = parse_date_time(d1$date, "%d %m %Y", locale = "fr_FR") %>%
  as.Date

Utilisation de la syntaxe XPath

L’exemple que l’on vient de voir permet de récupérer les données du blog Confusionnisme. Il se trouve que ce code fonctionne presque aussi bien pour le blog Conspis hors de nos vi[ll]es : en effet, celui-ci utilisant aussi le moteur de blog WordPress, la structure de ses pages est quasiment identique à celle que l’on vient de voir. Voici le code complet pour récupérer les 5 pages de ce blog :

d2 = data_frame()

for(i in 1:5) {
  
  h = html(paste0("http://conspishorsdenosvies.noblogs.org/page/", i))
  
  d2 = rbind(d2, data_frame(
    url = html_nodes(h, "#content .entry-title a") %>% html_attr("href"),
    title = html_nodes(h, "#content .entry-title a") %>% html_text,
    date = html_nodes(h, "#content .entry-date") %>% html_text,
    tags = html_nodes(h, ".tag-links") %>%
      sapply(function(x) html_nodes(x, xpath = "a[@rel='tag']") %>%
               html_text %>%
               paste0(collapse = ";"))
  ))
  
}

d2$date = parse_date_time(d2$date, "%d/%m/%Y") %>% as.Date

On remarquera que plusieurs petites choses ont changé : par exemple, sur le blog Conspis hors de nos vi[ll]es, les dates sont affichées dans un format dd/mm/yyyy qui ne nécessite pas de conversion, car chaque élément de la date est donné sous la forme d’un chiffre. On remarquera aussi que l’emplacement de la date a changé, car le gabarit graphique du blog diffère de celui de Confusionnisme et place cette information dans un élément différent du code source de la page.

Le changement le plus important ici concerne l’utilisation de la syntaxe XPath : en effet, pour récupérer les mots-clés, il nous a fallu limiter ceux-ci à ceux se trouvant dans des hyperliens (<a>) dont la propriété rel est égale à tag, pour ne pas également récupérer les mots-clés correspondant à des catégories du blog. La syntaxe XPath est un peu plus alambiquée : ici, c’est l’expression a[@rel='tag'] qui accomplit l’opération souhaitée, à condition d’être bien passée à l’argument xpath de la fonction html_nodes.

Combinaison des résultats

Il nous reste un blog à couvrir : Conspiracy Watch. Le code pour celui-ci diffère assez fondamentalement des blogs précédents du point de vue de la syntaxe de ses pages, qui utilisent un moteur de blog complètement différent de WordPress. Après lecture de la source, on arrive au code suivant, qui récupère les mêmes variables que récupérées pour les deux autres blogs :

d3 = data_frame()

for(i in seq(0, 1180, 20)) {
  
  h = html(paste0("http://www.conspiracywatch.info/?start=", i))
  
  d3 = rbind(d3, data_frame(
    url = html_nodes(h, "#mod_1260437 .titre a") %>% html_attr("href"),
    title = html_nodes(h, "#mod_1260437 .titre") %>% html_text %>% str_trim,
    date = html_nodes(h, "#mod_1260437 .cel_pied .date") %>% html_text,
    tags = html_nodes(h, "#mod_1260437 .cel_pied") %>%
      sapply(function(x) html_nodes(x, ".objet-tag a") %>%
               html_text %>%
               paste0(collapse = ";"))
  ))
  
}

d3$url = paste0("http://www.conspiracywatch.info", d3$url)
d3$date = parse_date_time(d3$date, "%d %m %Y", locale = "fr_FR") %>% as.Date

Il ne reste plus qu’à combiner les différents résultats de nos récupérations, de les ordonner par date de publication, puis d’harmoniser les mots-clés a minima, en supprimant les traits d’union et en s’assurant qu’ils ne contiennent pas de lettres majuscules :

d <- rbind(d1, d2, d3) %>% arrange(date)
d$tags <- gsub("-", " ", d$tags) %>% tolower()

L’inspection du résultat montre que l’on dispose à présent d’un jeu de données contenant les métadonnées de 1,268 billets de blogs, dont l’immense majorité proviennent de Conspiracy Watch :

# nombre de billets récupérés
nrow(d)
# sources des billets
table(substr(d$url, 1, 25))

Il ne reste plus qu’à sauvegarder ce résultat, pour réutilisation future :

write_csv(d, "data/conspi.csv")

  1. Si vous ne connaissez rien aux langages HTML et CSS, c’est le moment ou jamais d’en apprendre les bases ! Un excellent site de référence pour ce faire est W3 Schools.

Export de données

Export de tableaux de données

On peut avoir besoin d’exporter un tableau de données dans R vers un fichier dans différents formats. La plupart des fonctions d’import disposent d’un équivalent permettant l’export de données. On citera notamment :

  • write_csv, write_delim, write_tsv (readr)permettent d’enregistrer un data frame ou un tibble dans un fichier au format texte délimité
  • write_sas (haven) permet d’exporter au format SAS
  • write_sav (haven) permet d’exporter au format SPSS
  • write_dta (haven) permet d’exporter au format Stata

L’extension readxl ne fournit pas de fonction pour exporter au format Excel. Par contre, on pourra passer par la fonction write.xlsx de l’extension openxlsx ou la fonction write.xlsx de l’extension xlsx. L’intérêt de l’extension openxlsx est de ne pas dépendre de Java à la différence de l’extension xlsx.

Pour le format dBase, on peut utiliser write.dbf (foreign).

Ces fonctions sont utiles si on souhaite diffuser des données à quelqu’un d’autre, ou entre deux logiciels.

Si vous travaillez sur des données de grandes dimensions, les formats texte peuvent être lents à exporter et importer. Dans ce cas, l’extension feather peut être utile : elle permet d’enregistrer un data frame au format feather, qui n’est pas le plus compact mais qui est extrêmement rapide à lire et écrire 1.

Les fonctions read_feather et write_feather permettent d’importer et exporter des tableaux de données dans ce format.

Exporter des objets spatiaux

On aura recours à l’extension maptools qui fournit les fonctions writePointsShape | maptools, writeLinesShape et writePolyShape pour exporter des données respectivement de type points, lignes et polygones au format Shapefile, et la fonction writeAsciiGrid pour exporter un objet raster au format ASCII grid.

Sauvegarder des objets

Une autre manière de sauvegarder des données est de les enregistrer au format RData. Ce format propre à R est compact, rapide, et permet d’enregistrer plusieurs objets R, quel que soit leur type, dans un même fichier.

Pour enregistrer des objets, il suffit d’utiliser la fonction save et de lui fournir la liste des objets à sauvegarder et le nom du fichier :

save(d, rp2012, tab, file = "fichier.RData")

Pour charger des objets préalablement enregistrés, utiliser load :

load("fichier.RData")

Les objets d, rp2012 et tab devraient alors apparaître dans votre environnement.

Attention, quand on utilise load, les objets chargés sont importés directement dans l’environnement en cours avec leur nom d’origine. Si d’autres objets du même nom existaient déjà, ils sont écrasés sans avertissement.

R propose différentes fonctions permettant d’exporter des données vers des formats variés.

Type de fichier souhaité Fonction Extension
texte write.table utils
CSV write.csv utils
CSV write_csv readr
Excel write.xlsx xlsx
dBase write.dbf foreign
SPSS write_sav haven
SPSS write.foreign foreign
Stata write.dta foreign
Stata write_dta haven
SAS write.foreign foreign
SPSS write.foreign foreign

À nouveau, pour plus de détails on se référera aux pages d’aide de ces fonctions et au manuel R Data Import/Export accessible à l’adresse suivante : http://cran.r-project.org/manuals.html.


  1. feather est un format compatible avec Python, R et Julia. Pour plus d’informations voir https://github.com/wesm/feather

Export de graphiques

Via l’interface de RStudio

L’export de graphiques est très facile avec RStudio. Lorsque l’on créé un graphique, ce dernier est affiché sous l’onglet Plots dans le quadrant inférieur droit. Il suffit de cliquer sur Export pour avoir accès à trois options différentes :

  • Save as image pour sauvegarder le graphique en tant que fichier image ;
  • Save as PDF pour sauvegarder le graphique dans un fichier PDF ;
  • Copy to Clipboard pour copier le graphique dans le presse-papier (et pouvoir ainsi le coller ensuite dans un document Word par exemple).

Sauvegarder le fichier en tant qu’image

Sauvegarder un graphique en tant qu’image avec RStudio
Sauvegarder un graphique en tant qu’image avec RStudio

La boîte de dialogue qui s’ouvre propose différentes options d’export :

  • le type de fichier désiré ;
  • le nom du fichier ;
  • le répertoire où le fichier doit être créé (par défaut, il s’agit du répertoire de travail) ;
  • la taille de l’image.

R peut exporter un graphique dans une grande variété de formats. Nous n’aborderons ici que les principaux. Les formats PNG, JPEG et TIFF sont des formats de type bitmap (on parle aussi d’images matricielles1). L’image est stockée sous forme de points, sa qualité dépendant de sa résolution, c’est-à-dire du nombre total de points qui la composent. L’intérêt des images matricielles est d’être toujours interprétées de manière identique quelque soit l’outil utilisé. Par contre, elles ne sont pas adaptées lorsque l’on souhaite effectuer des retouches avec un logiciel de dessin.

Pour une utilisation sur un site web, on privilégiera une résolution d’image modérée (entre 400 et 800 pixels de largeur) et les formats PNG ou JPEG. Pour un document destiné à être imprimé, on priviligiera une résolution plus élevée, pour éviter un phénomène dit de pixellisation.

Les images vectorielles2 ont l’avantage de pouvoir être redimensionnées à volonté sans perte de qualité et produisent des fichiers en général de plus petite taille3. Elles sont donc tout à fait adaptées pour l’impression. Si l’on souhaite importer l’image dans Word, on choisira le format Metafile (le seul compris par ce logiciel). Pour Libre Office ou Open Office, on choisira le format SVG.

SVG (scalable vector graphic4) est un format libre permettant de décrire une image vectorielle. Les fichiers SVG peuvent être directement lus par la majorité des navigateurs récents (Firefox, Chrome, …). De plus, le logiciel libre de dessins Inkscape5 permet d’éditer et de modifier des fichiers SVG. Ce format est donc tout à fait adapté pour les graphiques que l’on souhaite retoucher avant publication. Depuis Inkscape, il sera possible de faire un export PNG en haute résolution pour intégration dans un fichier Word.

On pourra modifier la taille de l’image avec les paramètres Height (hauteur) et Width (largeur). En cliquant sur Update Preview la prévisulation du rendu final sera mise à jour.

Sauvegarder le graphique en PDF

Sauvegarder un graphique en PDF avec RStudio
Sauvegarder un graphique en PDF avec RStudio

Les options de la boîte de dialogue permettent de modifier la taille du fichier PDF et, bien entendu, d’indiquer le nom et le répertoire du fichier à créer.

En cliquant sur Preview, RStudio générera un fichier temporaire afin de visualiser le rendu final.

Copier le graphique dans le presse-papier

Copier un graphique dans le presse-papier avec RStudio
Copier un graphique dans le presse-papier avec RStudio

Il est possible de redimensionner le graphique. De plus, on précisera si l’on souhaite copier une version matricielle (bitmap) ou vectorielle (metafile) du graphique.

Export avec les commandes de R

On peut également exporter les graphiques dans des fichiers de différents formats directement avec des commandes R. Ceci a l’avantage de fonctionner sur toutes les plateformes et de faciliter la mise à jour du graphique exporté (on n’a qu’à relancer les commandes concernées pour que le fichier externe soit mis à jour).

La première possibilité est d’exporter le contenu d’une fenêtre déjà existante à l’aide de la fonction dev.print. On doit fournir à celle-ci le format de l’export (option device) et le nom du fichier (option file).

Par exemple :

boxplot(rnorm(100))
dev.print(device = png, file = "export.png", width = 600)

Les formats de sortie possibles varient selon les plateformes, mais on retrouve partout les formats bitmap png, jpeg, tiff et les formats vectoriels svg, postscript ou pdf.

L’autre possibilité est de rediriger directement la sortie graphique dans un fichier, avant d’exécuter la commande générant la figure. On doit pour cela faire appel à l’une des commandes permettant cette redirection. Les plus courantes sont png, jpeg et tiff pour les formats bitmap, svg, pdf, postscript et win.metafile pour les formats vectoriels.

Ces fonctions prennent différentes options permettant de personnaliser la sortie graphique. Les plus courantes sont width et height qui donnent la largeur et la hauteur de l’image générée (en pixels pour les images bitmap, en pouces pour les images vectorielles) et pointsize qui donne la taille de base des polices de caractère utilisées.

png(file = "out.png", width = 800, height = 700)
plot(rnorm(100))
dev.off()
pdf(file = "out.pdf", width = 9, height = 9, pointsize = 10)
plot(rnorm(150))
dev.off()

Il est nécessaire de faire un appel à la fonction dev.off après génération du graphique pour que le résultat soit bien écrit dans le fichier de sortie (dans le cas contraire on se retrouve avec un fichier vide).

Export avec ggplot2

Les graphiques produits par ggplot2 peuvent être sauvegardés manuellement, comme vu précédemment, ou programmatiquement. Pour sauvegarder le dernier graphique affiché par ggplot2 au format PNG, il suffit d’utiliser la fonction ggsave, qui permet d’en régler la taille (en pouces) et la résolution (en pixels par pouce ; 72 par défaut) :

ggsave("mon_graphique.png", width = 11, height = 8)

De la même manière, pour sauvegarder n’importe quel graphique construit avec ggplot2 et stocké dans un objet, il suffit de préciser le nom de cet objet, comme ci-dessous, où l’on sauvegarde le graphique contenu dans l’objet p au format vectoriel PDF, qui préserve la netteté du texte et des autres éléments du graphique à n’importe quelle résolution d’affichage :

ggsave("mon_graphique.pdf",
  plot = p,
  width = 11, height = 8
)

  1. Voir http://fr.wikipedia.org/wiki/Image_matricielle.

  2. Voir http://fr.wikipedia.org/wiki/Image_vectorielle.

  3. Sauf dans le cas des graphiques complexes reposant sur des dégradés de couleurs, comme les cartes produites à partir de rasters. Auquel cas, il sera parfois préférable de privilégier un export dans un format bitmap.

  4. Voir https://www.wikiwand.com/fr/Scalable_Vector_Graphics.

  5. téléchargeable gratuitement sur https://inkscape.org/fr/.

Statistique univariée

On entend par statistique univariée l’étude d’une seule variable, que celle-ci soit quantitative ou qualitative. La statistique univariée fait partie de la statistique descriptive.

Nous utiliserons dans ce chapitre les données de l’enquête Histoire de vie 2003 fournies avec l’extension questionr.

library(questionr)
data("hdv2003")
d <- hdv2003

Variable quantitative

Principaux indicateurs

Comme la fonction str nous l’a indiqué, notre tableau d contient plusieurs variables numériques ou variables quantitatives, dont la variable heures.tv qui représente le nombre moyen passé par les enquêtés à regarder la télévision quotidiennement. On peut essayer de déterminer quelques caractéristiques de cette variable, en utilisant les fonctions mean (moyenne), sd (écart-type), min (minimum), max (maximum) et range (étendue) :

mean(d$heures.tv)
[1] NA
mean(d$heures.tv, na.rm = TRUE)
[1] 2.246566
sd(d$heures.tv, na.rm = TRUE)
[1] 1.775853
min(d$heures.tv, na.rm = TRUE)
[1] 0
max(d$heures.tv, na.rm = TRUE)
[1] 12
range(d$heures.tv, na.rm = TRUE)
[1]  0 12

On peut lui ajouter la fonction median qui donne la valeur médiane, quantile qui calcule plus généralement tout type de quantiles, et le très utile summary qui donne toutes ces informations ou presque en une seule fois, avec en prime le nombre de valeurs manquantes (NA) :

median(d$heures.tv, na.rm = TRUE)
[1] 2
quantile(d$heures.tv, na.rm = TRUE)
  0%  25%  50%  75% 100% 
   0    1    2    3   12 
summary(d$heures.tv)
Min. 1st Qu. Median Mean 3rd Qu. Max. NA’s
0 1 2 2.246566 3 12 5

La fonction summary est une fonction générique qui peut être utilisée sur tout type d’objet, y compris un tableau de données. Essayez donc summary(d).

Histogramme

Tout cela est bien pratique, mais pour pouvoir observer la distribution des valeurs d’une variable quantitative, il n’y a quand même rien de mieux qu’un bon graphique.

On peut commencer par un histogramme de la répartition des valeurs. Celui-ci peut être généré très facilement avec la fonction hist :

hist(d$heures.tv, main = "Nombre d'heures passées devant la télé par jour", xlab = "Heures", ylab = "Effectif")
Exemple d’histogramme

Sous RStudio, les graphiques s’affichent dans l’onglet Plots du quadrant inférieur droit. Il est possible d’afficher une version plus grande de votre graphique en cliquant sur Zoom.

Ici, les options main, xlab et ylab permettent de personnaliser le titre du graphique, ainsi que les étiquettes des axes. De nombreuses autres options existent pour personnaliser l’histogramme, parmi celles-ci on notera :

  • probability si elle vaut TRUE, l’histogramme indique la proportion des classes de valeurs au lieu des effectifs.
  • breaks permet de contrôler les classes de valeurs. On peut lui passer un chiffre, qui indiquera alors le nombre de classes, un vecteur, qui indique alors les limites des différentes classes, ou encore une chaîne de caractère ou une fonction indiquant comment les classes doivent être calculées.
  • col la couleur de l’histogramme1.

Voir la page d’aide de la fonction hist pour plus de détails sur les différentes options. Les deux figures ci-après sont deux autres exemples d’histogramme.

hist(d$heures.tv, main = "Heures de télé en 7 classes", breaks = 7, xlab = "Heures", ylab = "Proportion", probability = TRUE, col = "orange")
Un autre exemple d’histogramme
hist(d$heures.tv, main = "Heures de télé avec classes spécifiées", breaks = c(0, 1, 4, 9, 12), xlab = "Heures", ylab = "Proportion", col = "red")
Encore un autre exemple d’histogramme

Densité et répartition cumulée

La fonction density permet d’obtenir une estimation par noyau2 de la distribution du nombre d’heures consacrées à regarder la télévision. Le paramètre na.rm = TRUE indique que l’on souhaite retirer les valeurs manquantes avant de calculer cette courbe de densité.

Le résultat de cette estimation est ensuite représenté graphiquement à l’aide de plot. L’argument main permet de spécifier le titre du graphique.

plot(density(d$heures.tv, na.rm = TRUE), main = "Heures consacrées à la télévision")
Courbe de densité

De manière similaire, on peut calculer la fonction de répartition empirique ou empirical cumulative distribution function en anglais avec la fonction ecdf. Le résultat obtenu peut, une fois encore, être représenté sur un graphique à l’aide de la fonction plot.

plot(ecdf(d$heures.tv))
Fonction de répartition empirique cumulée

Boîtes à moustaches

Les boîtes à moustaches, ou boxplots en anglais, sont une autre représentation graphique de la répartition des valeurs d’une variable quantitative. Elles sont particulièrement utiles pour comparer les distributions de plusieurs variables ou d’une même variable entre différents groupes, mais peuvent aussi être utilisées pour représenter la dispersion d’une unique variable. La fonction qui produit ces graphiques est la fonction boxplot.

boxplot(d$heures.tv, main = "Nombre d'heures passées devant la télé par jour", ylab = "Heures")
Exemple de boîte à moustaches

Comment interpréter ce graphique ? On le comprendra mieux à partir de la figure ci-après3.

boxplot(d$heures.tv, col = grey(0.8), main = "Nombre d'heures passées devant la télé par jour", ylab = "Heures")
abline(h = median(d$heures.tv, na.rm = TRUE), col = "navy", lty = 2)
text(1.35, median(d$heures.tv, na.rm = TRUE) + 0.15, "Médiane", col = "navy")
Q1 <- quantile(d$heures.tv, probs = 0.25, na.rm = TRUE)
abline(h = Q1, col = "darkred")
text(1.35, Q1 + 0.15, "Q1 : premier quartile", col = "darkred", lty = 2)
Q3 <- quantile(d$heures.tv, probs = 0.75, na.rm = TRUE)
abline(h = Q3, col = "darkred")
text(1.35, Q3 + 0.15, "Q3 : troisième quartile", col = "darkred", lty = 2)
arrows(x0 = 0.7, y0 = quantile(d$heures.tv, probs = 0.75, na.rm = TRUE), x1 = 0.7, y1 = quantile(d$heures.tv, probs = 0.25, na.rm = TRUE), length = 0.1, code = 3)
text(0.7, Q1 + (Q3 - Q1) / 2 + 0.15, "h", pos = 2)
mtext("L'écart inter-quartile h contient 50 % des individus", side = 1)
abline(h = Q1 - 1.5 * (Q3 - Q1), col = "darkgreen")
text(1.35, Q1 - 1.5 * (Q3 - Q1) + 0.15, "Q1 -1.5 h", col = "darkgreen", lty = 2)
abline(h = Q3 + 1.5 * (Q3 - Q1), col = "darkgreen")
text(1.35, Q3 + 1.5 * (Q3 - Q1) + 0.15, "Q3 +1.5 h", col = "darkgreen", lty = 2)
Interprétation d’une boîte à moustaches

Le carré au centre du graphique est délimité par les premiers et troisième quartiles, avec la médiane représentée par une ligne plus sombre au milieu. Les « fourchettes » s’étendant de part et d’autres vont soit jusqu’à la valeur minimale ou maximale, soit jusqu’à une valeur approximativement égale au quartile le plus proche plus 1,5 fois l’écart interquartile. Les points se situant en-dehors de cette fourchette sont représentés par des petits ronds et sont généralement considérés comme des valeurs extrêmes, potentiellement aberrantes.

On peut ajouter la représentation des valeurs sur le graphique pour en faciliter la lecture avec des petits traits dessinés sur l’axe vertical (fonction rug) :

boxplot(d$heures.tv, main = "Nombre d'heures passées devant la télé par\njour", ylab = "Heures")
rug(d$heures.tv, side = 2)
Boîte à moustaches avec représentation des valeurs

Variable qualitative

Tris à plat

La fonction la plus utilisée pour le traitement et l’analyse des variables qualitatives (variable prenant ses valeurs dans un ensemble de modalités) est sans aucun doute la fonction table, qui donne les effectifs de chaque modalité de la variable, ce qu’on appelle un tri à plat ou tableau de fréquences.

table(d$sexe)
Homme Femme
899 1101

La tableau précédent nous indique que parmi nos enquêtés on trouve 899 hommes et 1101 femmes.

Quand le nombre de modalités est élevé, on peut ordonner le tri à plat selon les effectifs à l’aide de la fonction sort.

table(d$occup)
Exerce une profession Chomeur Etudiant, eleve Retraite Retire des affaires Au foyer Autre inactif
1049 134 94 392 77 171 83
sort(table(d$occup))
Retire des affaires Autre inactif Etudiant, eleve Chomeur Au foyer Retraite Exerce une profession
77 83 94 134 171 392 1049
sort(table(d$occup), decreasing = TRUE)
Exerce une profession Retraite Au foyer Chomeur Etudiant, eleve Autre inactif Retire des affaires
1049 392 171 134 94 83 77

À noter que la fonction table exclut par défaut les non-réponses du tableau résultat. L’argument useNA de cette fonction permet de modifier ce comportement :

  • avec useNA="no" (valeur par défaut), les valeurs manquantes ne sont jamais incluses dans le tri à plat ;
  • avec useNA="ifany", une colonne NA est ajoutée si des valeurs manquantes sont présentes dans les données ;
  • avec useNA="always", une colonne NA est toujours ajoutée, même s’il n’y a pas de valeurs manquantes dans les données.

On peut donc utiliser :

table(d$trav.satisf, useNA = "ifany")
Satisfaction Insatisfaction Equilibre NA
480 117 451 952

L’utilisation de summary permet également l’affichage du tri à plat et du nombre de non-réponses :

summary(d$trav.satisf)
  Satisfaction Insatisfaction      Equilibre           NA's 
           480            117            451            952 

Pour obtenir un tableau avec la répartition en pourcentages, on peut utiliser la fonction freq de l’extension questionr4.

freq(d$qualif)
n % val%
Ouvrier specialise 203 10.2 12.3
Ouvrier qualifie 292 14.6 17.7
Technicien 86 4.3 5.2
Profession intermediaire 160 8.0 9.7
Cadre 260 13.0 15.7
Employe 594 29.7 35.9
Autre 58 2.9 3.5
NA 347 17.3 NA

La colonne n donne les effectifs bruts, la colonne % la répartition en pourcentages et val% la répartition en pourcentages, données manquantes exclues. La fonction accepte plusieurs paramètres permettant d’afficher les totaux, les pourcentages cumulés, de trier selon les effectifs ou de contrôler l’affichage. Par exemple :

freq(d$qualif, cum = TRUE, total = TRUE, sort = "inc", digits = 2, exclude = NA)
n % %cum
Autre 58 3.51 3.51
Technicien 86 5.20 8.71
Profession intermediaire 160 9.68 18.39
Ouvrier specialise 203 12.28 30.67
Cadre 260 15.73 46.40
Ouvrier qualifie 292 17.66 64.07
Employe 594 35.93 100.00
Total 1653 100.00 100.00

La colonne %cum indique ici le pourcentage cumulé, ce qui est ici une très mauvaise idée puisque pour ce type de variable cela n’a aucun sens. Les lignes du tableau résultat ont été triés par effectifs croissants, les totaux ont été ajoutés, les non-réponses exclues et les pourcentages arrondis à deux décimales.

La fonction freq est également en mesure de tenir compte des étiquettes de valeurs lorsqu’on utilise des données labellisées. Ainsi :

data(fecondite)
describe(femmes$region)
[2000 obs.] Région de résidence
labelled double: 4 4 4 4 4 3 3 3 3 3 ...
min: 1 - max: 4 - NAs: 0 (0%) - 4 unique values
4 value labels: [1] Nord [2] Est [3] Sud [4] Ouest

             n     %
[1] Nord   707  35.4
[2] Est    324  16.2
[3] Sud    407  20.3
[4] Ouest  562  28.1
Total     2000 100.0
freq(femmes$region)
n % val%
[1] Nord 707 35.4 35.4
[2] Est 324 16.2 16.2
[3] Sud 407 20.3 20.3
[4] Ouest 562 28.1 28.1
freq(femmes$region, levels = "labels")
n % val%
Nord 707 35.4 35.4
Est 324 16.2 16.2
Sud 407 20.3 20.3
Ouest 562 28.1 28.1
freq(femmes$region, levels = "values")
n % val%
707 35.4 35.4
324 16.2 16.2
407 20.3 20.3
562 28.1 28.1

Pour plus d’informations sur la fonction freq, consultez sa page d’aide en ligne avec ?freq ou help("freq").

Représentation graphique

Pour représenter la répartition des effectifs parmi les modalités d’une variable qualitative, on a souvent tendance à utiliser des diagrammes en secteurs (camemberts). Ceci est possible sous R avec la fonction pie, mais la page d’aide de la dite fonction nous le déconseille assez vivement : les diagrammes en secteur sont en effet une mauvaise manière de présenter ce type d’information, car l’oeil humain préfère comparer des longueurs plutôt que des surfaces5.

On privilégiera donc d’autres formes de représentations, à savoir les diagrammes en bâtons et les diagrammes de Cleveland.

Les diagrammes en bâtons sont utilisés automatiquement par R lorsqu’on applique la fonction générique plot à un tri à plat obtenu avec table. On privilégiera cependant ce type de représentations pour les variables de type numérique comportant un nombre fini de valeurs. Le nombre de frères, soeurs, demi-frères et demi-soeurs est un bon exemple :

plot(table(d$freres.soeurs), main = "Nombre de frères, soeurs, demi-frères et demi-soeurs", ylab = "Effectif")
Exemple de diagramme en bâtons

Pour les autres types de variables qualitatives, on privilégiera les diagrammes de Cleveland, obtenus avec la fonction dotchart. On doit appliquer cette fonction au tri à plat de la variable, obtenu avec table6 :

dotchart(as.matrix(table(d$clso))[, 1], main = "Sentiment d'appartenance à une classe sociale", pch = 19)
Exemple de diagramme de Cleveland

Il est possible d’entrer directement la commande suivante dans la console :

dotchart(table(d$clso))

R produira bien le diagramme de Cleveland désiré mais affichera un message d’avertissement (Warning) car pour des raisons liées au fonctionnement interne de la fonction dotchart, il est attendu une matrice ou un vecteur, non un objet de type table. Pour éviter cet avertissement, il est nécessaire de faire appel à la fonction as.matrix.

dotchart(as.matrix(table(d$clso)))

Dans le cas présent, on voit apparaître un chiffre 1 au-dessus des modalités. En fait, dotchart peut être appliqué au résultat d’un tableau croisé à deux entrées, auquel cas il présentera les résultats pour chaque colonne. Comme dans l’exemple ci-après.

dotchart(as.matrix(table(d$clso, d$sexe)))

Cela ne résoud pas le problème pour notre diagramme de Cleveland issu d’un tri à plat simple. Pour bien comprendre, la fonction as.matrix a produit un objet à deux dimensions ayant une colonne et plusieurs lignes. On indiquera à R que l’on ne souhaite extraire la première colonne avec [, 1] (juste après l’appel à as.matrix). C’est ce qu’on appelle l’indexation, abordée plus en détail dans le chapitre Listes et tableaux de données.

Quand la variable comprend un grand nombre de modalités, il est préférable d’ordonner le tri à plat obtenu à l’aide de la fonction sort :

dotchart(as.matrix(sort(table(d$qualif)))[, 1], main = "Niveau de qualification")
Exemple de diagramme de Cleveland ordonné

L’agument pch, qui est utilisé par la plupart des graphiques de type points, permet de spécifier le symbole à utiliser. Il peut prendre soit un nombre entier compris entre 0 et 25, soit un charactère textuel (voir ci-dessous).

Tableaux faciles avec gtsummary

L’extension gtsummary permets de réaliser facilement des tableaux univariés grace à la fonction tbl_summary. Le résultat produit des tableaux très propres, notamment dans le cadre de rapports automatisés au format Rmarkdown (voir le chapitre dédié).

On peut indiquer à la fois des variables quantitatives et qualitatives.

library(gtsummary)
d %>% tbl_summary(include = c("heures.tv", "occup", "qualif"))
Characteristic N = 2,0001
heures.tv 2.00 (1.00, 3.00)
Unknown 5
occup
Exerce une profession 1,049 (52%)
Chomeur 134 (6.7%)
Etudiant, eleve 94 (4.7%)
Retraite 392 (20%)
Retire des affaires 77 (3.9%)
Au foyer 171 (8.6%)
Autre inactif 83 (4.2%)
qualif
Ouvrier specialise 203 (12%)
Ouvrier qualifie 292 (18%)
Technicien 86 (5.2%)
Profession intermediaire 160 (9.7%)
Cadre 260 (16%)
Employe 594 (36%)
Autre 58 (3.5%)
Unknown 347

1 Statistics presented: Median (IQR); n (%)

Il est possible de personnaliser les statisques présentées (par exemple moyenne et écart-type à la place de la médiane et l’intervale inter-quartile). De plus, tbl_summary prend en compte les étiquettes de variables si elles ont été définies (voir le chapitre dédié). Il est aussi possible de franciser la présentation des résultats.

library(labelled)
var_label(d$heures.tv) <- "Heures quotidiennes devant la télévision"
var_label(d$occup) <- "Activité"
theme_gtsummary_language("fr", decimal.mark = ",", big.mark = " ")
Setting `language: fr` theme
d %>% tbl_summary(
  include = c("heures.tv", "occup"),
  statistic = list(all_continuous() ~ "{mean} ({sd})")
)
Caractéristique N = 2 0001
Heures quotidiennes devant la télévision 2,25 (1,78)
Manquant 5
Activité
Exerce une profession 1 049 (52%)
Chomeur 134 (6,7%)
Etudiant, eleve 94 (4,7%)
Retraite 392 (20%)
Retire des affaires 77 (3,9%)
Au foyer 171 (8,6%)
Autre inactif 83 (4,2%)

1 Statistique présentée: Moyenne (ET); n (%)

Pour une présentation de toutes les possibilités offertes, voir la vignette dédiée sur http://www.danieldsjoberg.com/gtsummary/articles/tbl_summary.html.

Exporter les graphiques obtenus

L’export de graphiques est très facile avec RStudio. Lorsque l’on créé un graphique, ce dernier est affiché sous l’onglet Plots dans le quadrant inférieur droit. Il suffit de cliquer sur Export pour avoir accès à trois options différentes :

  • Save as image pour sauvegarder le graphique en tant que fichier image ;
  • Save as PDF pour sauvegarder le graphique dans un fichier PDF ;
  • Copy to Clipboard pour copier le graphique dans le presse-papier (et pouvoir ainsi le coller ensuite dans un document Word par exemple).

Pour une présentation détaillée de l’export de graphiques avec RStudio, ainsi que pour connaître les commandes R permettant d’exporter des graphiques via un script, on pourra se référer au chapitre dédié.


  1. Il existe un grand nombre de couleurs prédéfinies dans R. On peut récupérer leur liste en utilisant la fonction colors en tapant simplement colors() dans la console, ou en consultant le document suivant : http://www.stat.columbia.edu/~tzheng/files/Rcolor.pdf.

  2. Voir https://fr.wikipedia.org/wiki/Estimation_par_noyau

  3. Le code ayant servi à générer cette figure est une copie quasi conforme de celui présenté dans l’excellent document de Jean Lobry sur les graphiques de base avec R, téléchargeable sur le site du Pôle bioinformatique lyonnais : http://pbil.univ-lyon1.fr/R/pdf/lang04.pdf.

  4. En l’absence de l’extension questionr, on pourra se rabattre sur la fonction prop.table avec la commande suivante : prop.table(table(d$qualif)).

  5. Voir en particulier https://www.data-to-viz.com/caveat/pie.html pour un exemple concret.

  6. Pour des raisons liées au fonctionnement interne de la fonction dotchart, on doit transformer le tri à plat en matrice, d’où l’appel à la fonction as.matrix.

Statistique bivariée

On entend par statistique bivariée l’étude des relations entre deux variables, celles-ci pouvant être quantitatives ou qualitatives. La statistique bivariée fait partie de la statistique descriptive.

La statistique univariée a quant à elle déjà été abordée dans un chapitre dédié.

Comme dans la partie précédente, on travaillera sur les jeux de données fournis avec l’extension questionr et tiré de l’enquête Histoire de vie et du recensement 1999 :

library(questionr)
data(hdv2003)
d <- hdv2003
data(rp99)

Deux variables quantitatives

La comparaison de deux variables quantitatives se fait en premier lieu graphiquement, en représentant l’ensemble des couples de valeurs. On peut ainsi représenter les valeurs du nombre d’heures passées devant la télévision selon l’âge.

plot(d$age, d$heures.tv)
Nombre d’heures de télévision selon l’âge

Le fait que des points sont superposés ne facilite pas la lecture du graphique. On peut utiliser une représentation avec des points semi-transparents.

plot(d$age, d$heures.tv, pch = 19, col = rgb(1, 0, 0, 0.1))
Nombre d’heures de télévision selon l’âge avec semi-transparence

Plus sophistiqué, on peut faire une estimation locale de densité et représenter le résultat sous forme de « carte ». Pour cela on commence par isoler les deux variables, supprimer les observations ayant au moins une valeur manquante à l’aide de la fonction complete.cases, estimer la densité locale à l’aide de la fonction kde2d de l’extension MASS1 et représenter le tout à l’aide d’une des fonctions image, contour ou filled.contour

library(MASS)
tmp <- d[, c("age", "heures.tv")]
tmp <- tmp[complete.cases(tmp), ]
filled.contour(kde2d(tmp$age, tmp$heures.tv), color = terrain.colors)
Représentation de l’estimation de densité locale

Une représentation alternative de la densité locale peut être obtenue avec la fonction smoothScatter.

smoothScatter(d[, c("age", "heures.tv")])
Représentation alternative de l’estimation de densité locale

Dans tous les cas, il n’y a pas de structure très nette qui semble se dégager. On peut tester ceci mathématiquement en calculant le coefficient de corrélation entre les deux variables à l’aide de la fonction cor :

cor(d$age, d$heures.tv, use = "complete.obs")
[1] 0.1776249

L’option use permet d’éliminer les observations pour lesquelles l’une des deux valeurs est manquante. Le coefficient de corrélation est très faible.

On va donc s’intéresser plutôt à deux variables présentes dans le jeu de données rp99, la part de diplômés du supérieur et la proportion de cadres dans les communes du Rhône en 1999.

À nouveau, commençons par représenter les deux variables.

plot(rp99$dipl.sup, rp99$cadres, ylab = "Part des cadres", xlab = "Part des diplomês du supérieur")
Proportion de cadres et proportion de diplômés du supérieur

Ça ressemble déjà beaucoup plus à une relation de type linéaire.

Calculons le coefficient de corrélation :

cor(rp99$dipl.sup, rp99$cadres)
[1] 0.8975282

C’est beaucoup plus proche de 1. On peut alors effectuer une régression linéaire complète en utilisant la fonction lm :

reg <- lm(cadres ~ dipl.sup, data = rp99)
summary(reg)

Call:
lm(formula = cadres ~ dipl.sup, data = rp99)

Residuals:
    Min      1Q  Median      3Q     Max 
-9.6905 -1.9010 -0.1823  1.4913 17.0866 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  1.24088    0.32988   3.762 0.000203 ***
dipl.sup     1.38352    0.03931  35.196  < 2e-16 ***
---
Signif. codes:  
0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 3.281 on 299 degrees of freedom
Multiple R-squared:  0.8056,    Adjusted R-squared:  0.8049 
F-statistic:  1239 on 1 and 299 DF,  p-value: < 2.2e-16

Le résultat montre que les coefficients sont significativement différents de 0. La part de cadres augmente donc avec celle de diplômés du supérieur (ô surprise). On peut très facilement représenter la droite de régression à l’aide de la fonction abline.

plot(rp99$dipl.sup, rp99$cadres, ylab = "Part des cadres", xlab = "Part des diplômés du supérieur")
abline(reg, col = "red")
Régression de la proportion de cadres par celle de diplômés du supérieur

On remarquera que le premier argument passé à la fonction lm a une syntaxe un peu particulière. Il s’agit d’une formule, utilisée de manière générale dans les modèles statistiques. On indique la variable d’intérêt à gauche et la variable explicative à droite, les deux étant séparées par un tilde ~ (obtenu sous Windows en appuyant simultanément sur les touches Alt Gr et 2). On remarquera que les noms des colonnes de notre tableau de données ont été écrites sans guillemets.

Dans le cas présent, nous avons calculé une régression linéaire simple entre deux variables, d’où l’écriture cadres ~ dipl.sup. Si nous avions voulu expliquer une variable z par deux variables x et y, nous aurions écrit z ~ x + y. Il est possible de spécifier des modèles encore plus complexes.

Pour un aperçu de la syntaxe des formules sous R, voir http://ww2.coastal.edu/kingw/statistics/R-tutorials/formulae.html.

Trois variables ou plus

Lorsque l’on souhaite représenter trois variables quantitatives simultanément, il est possible de réaliser un nuage de points représentant les deux premières variables sur l’axe horizontal et l’axe vertical et en faisant varier la taille des points selon la troisième variable, en utilisant l’argument cex de la fonction plot.

plot(rp99$dipl.aucun, rp99$tx.chom, cex = rp99$pop.tot / 10^4)
Nuage de points avec taille des points proportionnels à une troisième variable

Lorsque l’on étudie un plus grand nombres de variables quantitatives, il est peut être utile de réaliser une matrice de nuages de points, qui compare chaque variable deux à deux et qui s’obtient facilement avec la fonction pairs.

pairs(rp99[, c("proprio", "hlm", "locataire", "maison")])
Matrice de nuages de points

Une variable quantitative et une variable qualitative

Représentations graphiques

Quand on parle de comparaison entre une variable quantitative et une variable qualitative, on veut en général savoir si la distribution des valeurs de la variable quantitative est la même selon les modalités de la variable qualitative. En clair : est ce que l’âge de ceux qui écoutent du hard rock est différent de l’âge de ceux qui n’en écoutent pas ?

Là encore, l’idéal est de commencer par une représentation graphique. Les boîtes à moustaches (boxplot en anglais) sont parfaitement adaptées pour cela.

Si on a construit des sous-populations d’individus écoutant ou non du hard rock, on peut utiliser la fonction boxplot.

d.hard <- subset(d, hard.rock == "Oui")
d.non.hard <- subset(d, hard.rock == "Non")
boxplot(d.hard$age, d.non.hard$age)
Boxplot de la répartition des âges (sous-populations)

Mais construire les sous-populations n’est pas nécessaire. On peut utiliser directement la version de boxplot prenant une formule en argument.

boxplot(age ~ hard.rock, data = d)
Boxplot de la répartition des âges (formule)

À première vue, ô surprise, la population écoutant du hard rock a l’air sensiblement plus jeune. Peut-on le tester mathématiquement ?

Les boîtes à moustache peuvent parfois être trompeuses car ne représentant qu’imparfaitement la distribution d’une variable quantitative2.

Les graphique de pirates ou pirateplot sont une visualisation alternative qui combinent :

  • un nuage de points représentant les données brutes ;
  • une barre verticale représentant la moyenne ;
  • un rectangle traduisant une inférence sur cette moyenne ;
  • une forme en haricot ou violon indiquant la distribution.

De tels graphiques peuvent être réalisés avec la fonction pirateplot de l’extension yarr. Par défaut, les rectangles représentent un intervalle bayésien crédible ou Bayesian Highest Density Intervals ou HDI de la moyenne. On peut représenter à la place des intervalles de confiance avec inf.method = "ci".

library(yarrr)
pirateplot(
  age ~ hard.rock,
  data = d,
  theme = 1, inf.method = "ci",
  bar.f.o = .1, bar.f.col = "grey10"
)
Graphique de pirates

Tests statistiques

On peut calculer la moyenne d’âge des deux groupes en utilisant la fonction tapply3 :

tapply(d$age, d$hard.rock, mean)
     Non      Oui 
48.30211 27.57143 

Pour un test de comparaison de deux moyennes (test t de Student), on pourra se référer au chapitre dédié aux test statistiques de comparaison.

Deux variables qualitatives

La comparaison de deux variables qualitatives s’appelle en général un tableau croisé. C’est sans doute l’une des analyses les plus fréquentes lors du traitement d’enquêtes en sciences sociales.

Tableau croisé

La manière la plus simple d’obtenir un tableau croisé est d’utiliser la fonction table en lui donnant en paramètres les deux variables à croiser. En l’occurrence nous allons croiser un recodage du niveau de qualification regroupé avec le fait de pratiquer un sport.

On commence par calculer la variable recodée et par afficher le tri à plat des deux variables :

d$qualif2 <- as.character(d$qualif)
d$qualif2[d$qualif %in% c("Ouvrier specialise", "Ouvrier qualifie")] <- "Ouvrier"
d$qualif2[d$qualif %in% c("Profession intermediaire", "Technicien")] <- "Intermediaire"
table(d$qualif2)
Autre Cadre Employe Intermediaire Ouvrier
58 260 594 246 495

Le tableau croisé des deux variables s’obtient de la manière suivante :

table(d$sport, d$qualif2)
Autre Cadre Employe Intermediaire Ouvrier
Non 38 117 401 127 381
Oui 20 143 193 119 114

Il est tout à fait possible de croiser trois variables ou plus. Par exemple :

table(d$sport, d$cuisine, d$sexe)
Var1 Var2 Var3 Freq
Non Non Femme 358
Homme 401
Oui Femme 389
Homme 129
Oui Non Femme 132
Homme 228
Oui Femme 222
Homme 141

Une alternative à la fonction table est la fonction xtabs. On indiquera à cette dernière le croisement à effectuer à l’aide d’une formule puis l’objet contenant nos données. Comme il ne s’agit pas d’un modèle avec une variable à expliquer, toutes les variables seront indiquées à la droite du symbole ~ et séparées par +.

xtabs(~sport, d)
Non Oui
1277 723
xtabs(~ sport + cuisine, d)
Non Oui
Non 759 518
Oui 360 363
xtabs(~ sport + cuisine + sexe, d)
sport cuisine sexe Freq
Non Non Femme 358
Homme 401
Oui Femme 389
Homme 129
Oui Non Femme 132
Homme 228
Oui Femme 222
Homme 141

On remarquera que le rendu par défaut est en général plus lisible car le nom des variables est indiqué, permettant de savoir quelle variable est affichée en colonnes et laquelle en lignes.

Si l’on utilise des données labellisées, la fonction xtabs ne prendra pas en compte les étiquettes de valeur.

data(fecondite)
xtabs(~ educ + region, femmes)
1 2 3 4
0 387 213 282 256
1 179 53 86 142
2 123 57 37 131
3 18 1 2 33

On pourra alors utiliser la fonction ltabs de l’extension question, qui fonctionne exactement comme xtabs, à ceci près qu’elle prendra en compte les étiquettes de variable et de valeur quand elles existent.

ltabs(~ educ + region, femmes)
[1] Nord [2] Est [3] Sud [4] Ouest
[0] aucun 387 213 282 256
[1] primaire 179 53 86 142
[2] secondaire 123 57 37 131
[3] supérieur 18 1 2 33

Pourcentages en ligne et en colonne

On n’a cependant que les effectifs, ce qui rend difficile les comparaisons. L’extension questionr fournit des fonctions permettant de calculer facilement les pourcentages lignes, colonnes et totaux d’un tableau croisé.

Les pourcentages lignes s’obtiennent avec la fonction lprop4. Celle-ci s’applique au tableau croisé généré par table ou xtabs  :

tab <- table(d$sport, d$qualif2)
lprop(tab)
Autre Cadre Employe Intermediaire Ouvrier Total
Non 3.571429 10.99624 37.68797 11.93609 35.80827 100
Oui 3.395586 24.27844 32.76740 20.20374 19.35484 100
Ensemble 3.508772 15.72898 35.93466 14.88203 29.94555 100
tab <- xtabs(~ sport + qualif2, d)
lprop(tab)
Autre Cadre Employe Intermediaire Ouvrier Total
Non 3.571429 10.99624 37.68797 11.93609 35.80827 100
Oui 3.395586 24.27844 32.76740 20.20374 19.35484 100
Ensemble 3.508772 15.72898 35.93466 14.88203 29.94555 100

Les pourcentages ligne ne nous intéressent guère ici. On ne cherche pas à voir quelle est la proportion de cadres parmi ceux qui pratiquent un sport, mais plutôt quelle est la proportion de sportifs chez les cadres. Il nous faut donc des pourcentages colonnes, que l’on obtient avec la fonction cprop :

cprop(tab)
Autre Cadre Employe Intermediaire Ouvrier Ensemble
Non 65.51724 45 67.50842 51.62602 76.9697 64.36782
Oui 34.48276 55 32.49158 48.37398 23.0303 35.63218
Total 100.00000 100 100.00000 100.00000 100.0000 100.00000

Dans l’ensemble, le pourcentage de personnes ayant pratiqué un sport est de 35,6 %. Mais cette proportion varie fortement d’une catégorie professionnelle à l’autre : 55,0 % chez les cadres contre 23,0 % chez les ouvriers.

Enfin, les pourcentage totaux s’obtiennent avec la fonction prop :

prop(tab)
Autre Cadre Employe Intermediaire Ouvrier Total
Non 2.298851 7.078040 24.25892 7.683001 23.049002 64.36782
Oui 1.209921 8.650938 11.67574 7.199032 6.896552 35.63218
Total 3.508772 15.728978 35.93466 14.882033 29.945553 100.00000

À noter qu’on peut personnaliser l’affichage de ces tableaux de pourcentages à l’aide de différentes options, dont digits qui règle le nombre de décimales à afficher et percent qui indique si on souhaite ou non rajouter un symbole % dans chaque case du tableau. Cette personnalisation peut se faire directement au moment de la génération du tableau et dans ce cas elle sera utilisée par défaut :

ctab <- cprop(tab, digits = 2, percent = TRUE)
ctab
Autre Cadre Employe Intermediaire Ouvrier Ensemble
Non 65.51724 45 67.50842 51.62602 76.9697 64.36782
Oui 34.48276 55 32.49158 48.37398 23.0303 35.63218
Total 100.00000 100 100.00000 100.00000 100.0000 100.00000

ou bien ponctuellement en passant les mêmes arguments à la fonction print :

ctab <- cprop(tab)
print(ctab, percent = TRUE)
       qualif2
sport   Autre  Cadre  Employe Intermediaire Ouvrier
  Non    65.5%  45.0%  67.5%   51.6%         77.0% 
  Oui    34.5%  55.0%  32.5%   48.4%         23.0% 
  Total 100.0% 100.0% 100.0%  100.0%        100.0% 
       qualif2
sport   Ensemble
  Non    64.4%  
  Oui    35.6%  
  Total 100.0%  

Représentation graphique

On peut obtenir une représentation graphique synthétisant l’ensemble des résultats obtenus sous la forme d’un graphique en mosaïque grâce à la fonction mosaicplot.

mosaicplot(qualif2 ~ sport, data = d, shade = TRUE, main = "Graphe en mosaïque")
Exemple de graphe en mosaïque

Comment interpréter ce graphique haut en couleurs5 ? Chaque rectangle représente une case de tableau. Sa largeur correspond aux pourcentages en colonnes (il y a beaucoup d’employés et d’ouvriers et très peu d’« Autre »). Sa hauteur correspond aux pourcentages en lignes : la proportion de sportifs chez les cadres est plus élevée que chez les employés. Enfin, la couleur de la case correspond au résidu du test du ² correspondant : les cases en rouge sont sous-représentées, les cases en bleu sur-représentées, et les cases blanches sont statistiquement proches de l’hypothèse d’indépendance.

Les graphiques en mosaïque permettent notamment de représenter des tableaux croisés à 3 ou 4 dimensions, voire plus.

L’extension vcd fournie une fonction mosaic fournissant plus d’options pour la création d’un graphique en mosaïque, permettant par exemple d’indiquer quelles variables doivent être affichées horizontalement ou verticalement, ou encore de colorier le contenu des rectangles en fonction d’une variable donnée, …

library(vcd)
mosaic(~ sport + cuisine + sexe, d, highlighting = "sexe", main = "Exemple de graphique en mosaïque à 3 dimensions")

Lorsque l’on s’intéresse principalement aux variations d’une variable selon une autre, par exemple ici à la pratique du sport selon le niveau de qualification, il peut être intéressant de présenter les pourcentages en colonne sous la forme de barres cumulées.

barplot(cprop(tab, total = FALSE), main = "Pratique du sport selon le niveau de qualification")
Exemple de barres cumulées

Tests statistiques

Pour un test de comparaison de proportions, un test du Chi² ou encore un test exact de Fisher, on pourra se référer au chapitre dédié aux test statistiques de comparaison.

Tableaux faciles avec gtsummary

La fonction tbl_summary de l’extension gtsummary accepte un argument by permettant de réaliser des croisements selon une variable catégorielle.

library(gtsummary)
theme_gtsummary_language("fr", decimal.mark = ",", big.mark = " ")
Setting `language: fr` theme
d %>%
  tbl_summary(
    include = c("hard.rock", "heures.tv", "sport", "qualif2"),
    by = "hard.rock"
  )
Caractéristique Non, N = 1 9861 Oui, N = 141
heures.tv 2,00 (1,00 – 3,00) 2,00 (2,00 – 3,75)
Manquant 5 0
sport
Non 1 268 (64%) 9 (64%)
Oui 718 (36%) 5 (36%)
qualif2
Autre 57 (3,5%) 1 (9,1%)
Cadre 260 (16%) 0 (0%)
Employe 587 (36%) 7 (64%)
Intermediaire 244 (15%) 2 (18%)
Ouvrier 494 (30%) 1 (9,1%)
Manquant 344 3

1 Statistique présentée: Médiane (EI); n (%)

Il est possible d’ajouter une colonne total avec add_overall et des tests statistiques avec add_p.

d %>%
  tbl_summary(
    include = c("hard.rock", "heures.tv", "sport", "qualif2"),
    by = "hard.rock"
  ) %>%
  add_overall(last = TRUE) %>%
  add_p()
Caractéristique Non, N = 1 9861 Oui, N = 141 Total, N = 2 0001 p-value2
heures.tv 2,00 (1,00 – 3,00) 2,00 (2,00 – 3,75) 2,00 (1,00 – 3,00) 0,4
Manquant 5 0 5
sport >0,9
Non 1 268 (64%) 9 (64%) 1 277 (64%)
Oui 718 (36%) 5 (36%) 723 (36%)
qualif2 0,088
Autre 57 (3,5%) 1 (9,1%) 58 (3,5%)
Cadre 260 (16%) 0 (0%) 260 (16%)
Employe 587 (36%) 7 (64%) 594 (36%)
Intermediaire 244 (15%) 2 (18%) 246 (15%)
Ouvrier 494 (30%) 1 (9,1%) 495 (30%)
Manquant 344 3 347

1 Statistique présentée: Médiane (EI); n (%)

2 Test statistique réalisé: test de Wilcoxon-Mann-Whitney; test du khi-deux d'indépendance; test exact de Fisher

Par défaut, les pourcentages affichés sont les pourcentages en colonne. Mais il est possible de les remplacer par les pourcentages en ligne avec l’argument percent.

d %>%
  dplyr::select(hard.rock, sport, qualif2) %>%
  tbl_summary(
    by = "hard.rock",
    percent = "row"
  ) %>%
  add_overall(last = TRUE)
Caractéristique Non, N = 1 9861 Oui, N = 141 Total, N = 2 0001
sport
Non 1 268 (99%) 9 (0,7%) 1 277 (100%)
Oui 718 (99%) 5 (0,7%) 723 (100%)
qualif2
Autre 57 (98%) 1 (1,7%) 58 (100%)
Cadre 260 (100%) 0 (0%) 260 (100%)
Employe 587 (99%) 7 (1,2%) 594 (100%)
Intermediaire 244 (99%) 2 (0,8%) 246 (100%)
Ouvrier 494 (100%) 1 (0,2%) 495 (100%)
Manquant 344 3 347

1 Statistique présentée: n (%)

Citons également la variante tbl_cross utilisable pour un tableau croisé de seulement deux variables (une en ligne et une en colonne).

d %>%
  tbl_cross(sport, hard.rock)
Caractéristique hard.rock Total
Non Oui
sport
Non 1 268 9 1 277
Oui 718 5 723
Total 1 986 14 2 000

Pour une présentation de toutes les possibilités offertes, voir la vignette dédiée sur http://www.danieldsjoberg.com/gtsummary/articles/tbl_summary.html.


  1. MASS est installée par défaut avec la version de base de R.

  2. Voir par exemple The boxplot and its pitfalls sur https://www.data-to-viz.com.

  3. La fonction tapply est présentée plus en détails dans le chapitre Manipulation de données.

  4. Il s’agit en fait d’un alias pour les francophones de la fonction rprop.

  5. Sauf s’il est imprimé en noir et blanc…

Introduction à ggplot2, la grammaire des graphiques

Ce chapitre est tiré d’une séance de cours de François Briatte et destinée à des étudiants de L2 sans aucune connaissance de R. Cette séance de cours est elle-même inspirée d’un exercice tiré d’un cours de Cosma Shalizi.

R possède un puissant moteur graphique interne, qui permet de dessiner dans un graphique en y rajoutant des segments, des points, du texte, ou toutes sortes d’autres symboles. Toutefois, pour produire un graphique complet avec les fonctions basiques de R, il faut un peu bricoler : d’abord, ouvrir une fenêtre ; puis rajouter des points ; puis rajouter des lignes ; tout en configurant les couleurs au fur-et-à-mesure ; puis finir par fermer la fenêtre graphique.

L’extension ggplot21, développée par Hadley Wickham et mettant en œuvre la grammaire graphique théorisée par Leland Wilkinson, devient vite indispensable lorsque l’on souhaite réaliser des graphiques plus complexes2. On renvoit le lecteur intéressé à l’ouvrage de Winston Chang, R Graphics Cookbook, disponible gratuitement dans sa deuxième édition à l’adresse suivante : https://r-graphics.org.

Ce chapitre, articulé autour d’une étude de cas, présente ggplot2 à partir d’un exemple simple de visualisation de séries temporelles, puis rentre dans le détail de sa syntaxe. Pour une présentation plus formelle, on pourra se référer au chapitre dédié de la section Approfondir.

Les données de l’exemple

Il y a quelques années, les chercheurs Carmen M. Reinhart et Kenneth S. Rogoff publiaient un article intitulé Growth in a Time of Debt, dans lequel ils faisaient la démonstration qu’un niveau élevé de dette publique nuisait à la croissance économique. Plus exactement, les deux chercheurs y défendaient l’idée que, lorsque la dette publique dépasse 90 % du produit intérieur brut, ce produit cesse de croître.

Cette conclusion, proche du discours porté par des institutions comme le Fonds Monétaire International, a alimenté plusieurs argumentaires politiques. Des parlementaires américains s’en ainsi sont servi pour exiger une diminution du budget fédéral, et surtout, la Commission européenne s’est appuyée sur cet argumentaire pour exiger que des pays comme la Grèce, durement frappés par la crise financière globale de 2008, adoptent des plans d’austérité drastiques.

Or, en tentant de reproduire les résultats de Reinhart et Rogoff, les chercheurs Thomas Herndon, Michael Ash et Robert Pollin y ont trouvé de nombreuses erreurs, ainsi qu’une bête erreur de calcul due à une utilisation peu attentive du logiciel Microsoft Excel. La révélation de ces erreurs donna lieu à un débat très vif entre adversaires et partisans des politiques économiques d’austérité, débat toujours autant d’actualité aujourd’hui.

Dans ce chapitre, on va se servir des données (corrigées) de Reinhart et Rogoff pour évaluer, de manière indépendante, la cohérence de leur argument sur le rapport entre endettement et croissance économique. Commençons par récupérer ces données au format CSV sur le site du chercheur américain Cosma Shalizi, qui utilise ces données dans l’un de ses exercices de cours :

# charger l'extension lisant le format CSV
library(readr)

# emplacement souhaité pour le jeu de données
file <- "data/debt.csv"

# télécharger le jeu de données s'il n'existe pas
if(!file.exists(file))
  download.file("http://www.stat.cmu.edu/~cshalizi/uADA/13/hw/11/debt.csv",
                file, mode = "wb")

# charger les données dans l'objet 'debt'
debt <- read_csv(file)
Warning: Missing column names filled in: 'X1' [1]

-- Column specification ------------------------------------
cols(
  X1 = col_double(),
  Country = col_character(),
  Year = col_double(),
  growth = col_double(),
  ratio = col_double()
)

Le code ci-dessus utilise la fonction read_csv de l’extension readr, dont on a recommandé l’utilisation dans un précédent chapitre. En l’absence de cette extension, on aurait pu utiliser la fonction de base read.csv.

Nettoyage des données

Les données de Reinhart et Rogoff contiennent, pour un échantillon de 20 pays occidentaux membres de la zone OCDE, la croissance de leur produit intérieur brut (PIB)3, et le ratio entre leur dette publique et ce produit, exprimé sous la forme d’un pourcentage Dette / PIB. Les données vont du milieu des années 1940 à la fin des années 2000. La première colonne du jeu de données ne contenant que les numéros des lignes, on va la supprimer d’entrée de jeu :

# inspection du jeu de données
str(debt)
tibble [1,171 x 5] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
 $ X1     : num [1:1171] 147 148 149 150 151 152 153 154 155 156 ...
 $ Country: chr [1:1171] "Australia" "Australia" "Australia" "Australia" ...
 $ Year   : num [1:1171] 1946 1947 1948 1949 1950 ...
 $ growth : num [1:1171] -3.56 2.46 6.44 6.61 6.92 ...
 $ ratio  : num [1:1171] 190 177 149 126 110 ...
 - attr(*, "spec")=
  .. cols(
  ..   X1 = col_double(),
  ..   Country = col_character(),
  ..   Year = col_double(),
  ..   growth = col_double(),
  ..   ratio = col_double()
  .. )
# suppression de la première colonne
debt <- debt[, -1]

Il faut aussi noter d’emblée que certaines mesures sont manquantes : pour certains pays, on ne dispose pas d’une mesure fiable du PIB et/ou de la dette publique. En conséquence, le nombre d’observations par pays est différent, et va de 40 observations pays-année pour la Grèce à 64 observations pays-année pour plusieurs pays comme l’Australie ou les États-Unis :

table(debt$Country)

  Australia     Austria     Belgium      Canada     Denmark 
         64          59          63          64          56 
    Finland      France     Germany      Greece     Ireland 
         64          54          59          40          63 
      Italy       Japan Netherlands New Zealand      Norway 
         59          54          53          64          64 
   Portugal       Spain      Sweden          UK          US 
         58          42          64          63          64 

Recodage d’une variable

Dernière manipulation préalable avant l’analyse : on va calculer la décennie de chaque observation, en divisant l’année de mesure par 10, et en multipliant la partie entière de ce résultat par 10. Cette manipulation très simple donne 1940 pour les mesures des années 1940 à 1949, 1950 pour les années 1950-1959, et ainsi de suite.

debt$Decade <- factor(10 * debt$Year %/% 10)

Voici, pour terminer, les premières lignes du jeu de données sur lequel on travaille :

head(debt)

Visualisation des données

Chargeons à présent l’extension graphique ggplot2 :

library(ggplot2)

Procédons désormais à quelques visualisations très simples de ces données. On dispose de trois variables continues : l’année, le taux de croissance du PIB, et le ratio Dette publique / PIB. Si l’on souhaite visualiser la croissance du PIB au cours du temps, la solution basique dans R s’écrit de la manière suivante :

with(debt, plot(Year, growth))

Le code de la visualisation est très simple et se lit : avec l’objet debt, construire le graphique montrant l’année d’observation Year en abcisse et le taux de croissance du PIB growth en ordonnée. Le code est compris de cette manière par R car la fonction plot comprend le premier argument comme étant la variable à représenter sur l’axe horizontal x, et le second comme la variable à représenter sur l’axe vertical y.

Le même graphique s’écrit de la manière suivante avec l’extension ggplot2 :

with(debt, qplot(Year, growth))

Comme on peut le voir, le code est très proche du code utilisé dans R base, la syntaxe signifiant toujours : avec le jeu de données debt, visualiser les variables Year sur l’axe x et growth sur l’axe y. Le résultat est similaire, bien que plusieurs paramètres graphiques aient changé : le fond gris clair, en particulier, est caractéristique du thème graphique par défaut de ggplot2, que l’on apprendra à modifier plus loin.

Par ailleurs, dans les deux exemples précédents, on a écrit with(debt, ...) pour indiquer que l’on travaillait avec l’objet debt. Lorsque l’on travaille avec l’extension ggplot2, il est toutefois plus commun d’utiliser l’argument data dans l’appel de qplot pour indiquer ce choix :

qplot(Year, growth, data = debt)

Visualisation par petits multiples

Cherchons désormais à mieux comprendre les variations du taux de croissance du PIB au fil des années.

Dans les graphiques précédents, on voit clairement que ce taux est très variable dans l’immédiat après-guerre, puis qu’il oscille entre environ -5 % et +15 %, puis qu’il semble chuter dramatiquement à la fin des années 2000, marquées par la crise financière globale. Mais comment visualiser ces variations pour chacun des vingt pays de l’échantillon ?

On va ici utiliser le principe de la visualisation par petits multiples, c’est-à-dire que l’on va reproduire le même graphique pour chacun des pays, et visualiser l’ensemble de ces graphiques dans une même fenêtre. Concrètement, il va donc s’agir de montrer la croissance annuelle du PIB en faisant apparaître chaque pays dans une facette différente du graphique.

ggplot2 permet d’effectuer cette opération en rajoutant au graphique précédent, au moyen de l’opérateur +, l’élément facet_wrap(~ Country) au graphique et qui signifie construire le graphique pour chaque valeur différente de la variable Country. On notera que la fonction facet_wrap utilise la syntaxe équation de R. Par défaut, ces facettes sont classées par ordre alphabétique :

qplot(Year, growth, data = debt) +
  facet_wrap(~ Country)

Voilà qui est beaucoup plus clair ! On aperçoit bien, dans ce graphique, les variations très importantes de croissance du PIB dans un pays comme l’Autriche, ruinée après la Seconde guerre mondiale, ou l’Irlande, très durement frappée par la crise financière globale en 2008 et 2009. On aperçoit aussi où se trouvent les données manquantes : voir le graphique de l’Espagne, par exemple.

Il faut noter ici un élément essentiel de la grammaire graphique de ggplot2, qui utilise une syntaxe additive, où différents éléments et paramètres graphiques peuvent être combinés en les additionnant, ce qui permet de construire et de modifier des graphiques de manière cumulative, pas à pas. Cette caractéristique permet de tâtonner, et de construire progressivement des graphiques très complets.

Visualisation en séries temporelles

Enfin, pour produire le même graphique que ci-dessus en utilisant des lignes plutôt que des points, il suffit d’utiliser l’argument geom = "line", ce qui peut être considéré comme une meilleure manière de visualiser des séries temporelles, mais qui tend aussi à rendre plus difficile la détection des périodes pour lesquelles il manque des données (voir, à nouveau, le graphique pour l’Espagne) :

qplot(data = debt, y = growth, x = Year, geom = "line") + 
  facet_wrap(~ Country)

Dans ce dernier exemple, on a défini l’axe y avant de définir l’axe x, en écrivant ces arguments de manière explicite ; de même, on a commencé par spécifier l’argument data, et l’on a terminé par l’argument geom. Cet ordre d’écriture permet de conserver une forme de cohérence dans l’écriture des fonctions graphiques.

Combinaisons d’éléments graphiques

On n’a pas encore visualisé le ratio Dette publique / PIB, l’autre variable du raisonnement de Reinhart et Rogoff. C’est l’occasion de voir comment rajouter des titres aux axes des graphiques, et d’utiliser les lignes en même temps que des points, toujours grâce à l’argument geom, qui peut prendre plusieurs valeurs (ici, "point" produit les points et "line" produit les lignes) :

qplot(data = debt, y = ratio, x = Year, geom = c("line", "point")) + 
  facet_wrap(~ Country) +
  labs(x = NULL,
       y = "Ratio dette publique / produit intérieur brut (%)\n")

Dans ce graphique, on a combiné deux objets géométriques (geom) pour afficher à la fois des points et des lignes. On a ensuite défini les titres des axes, en supprimant celui de l’axe x, et en rajoutant un peu d’espace entre le titre de l’axe y et l’axe lui-même grâce à la chaîne de caractères finale \n, qui rajoute une ligne vide entre ces deux éléments4.

Les différents exemples vus dans cette section montrent qu’il va falloir apprendre un minimum de syntaxe graphique pour parvenir à produire des graphiques avec ggplot2. Ce petit investissement permet de savoir très vite produire de très nombreux types de graphiques, assez élégants de surcroît, et très facilement modifiables à l’aide de toutes sortes de paramètres optionnels.

Aussi élégants que soient vos graphiques, il ne vous dispense évidemment pas de réfléchir à ce que vous êtes en train de visualiser, un graphique très élégant pouvant naturellement être complètement erroné, en particulier si les données de base du graphique ont été mal mesurées… ou endommagées.

Composition graphique avec ggplot2

La section précédente a montré comment utiliser la fonction qplot (quick plot). La syntaxe complète de l’extension ggplot2 passe par une autre fonction, ggplot, qui permet de mieux comprendre les différents éléments de sa grammaire graphique. Dans cette section, on va détailler cette syntaxe pour en tirer un graphique plus complexe que les précédents.

Commençons par créer un treillis de base au graphique :

p <- ggplot(data = debt, aes(y = growth, x = ratio))

Aucun graphique ne s’affiche ici : en effet, ce que l’on a stocké, dans l’objet p, n’est pas un graphique complet, mais une base de travail. Cette base définit les coordonnées x et y du graphique dans l’argument aes (aesthetics). Ici, on a choisi de mettre la variable dépendante de Reinhart et Rogoff, growth (le taux de croissance du PIB), sur l’axe y, et la variable indépendante ratio (le ratio Dette publique / PIB) sur l’axe x.

Rajoutons désormais un objet géométrique, geom_point, qui va projeter, sur le graphique, des points aux coordonnées précédemment définies, et divisons le graphique par un petit multiple, en projetant les points de chaque décennie dans une facette différente du graphique. Ce graphique propose une décomposition temporelle de la relation étudiée par Reinhart et Rogoff :

p + geom_point() +
  facet_grid(. ~ Decade)

Le paramètre facet_grid, qui utilise aussi la syntaxe équation, permet de créer des facettes plus compliquées que celles créées par le paramètre facet_wrap, même si, dans nos exemples, on aurait pu utiliser aussi bien l’un que l’autre.

Le graphique ci-dessus présente un problème fréquent : l’axe horizontal du graphique, très important puisque Reinhart et Rogoff évoquent un seuil fatidique, pour la croissance, de 90% du PIB, est illisible. Grâce à l’argument scale_x_continuous, on va pouvoir clarifier cet axe en n’y faisant figurer que certaines valeurs :

p + geom_point() +
  facet_grid(. ~ Decade) +
  scale_x_continuous(breaks = seq(0, 200, by = 100))

Ces réglages nous conviennent : on va donc les sauvegarder dans l’objet p, de manière à continuer de construire notre graphique en incluant ces différents éléments.

p <- p + geom_point() +
  facet_grid(. ~ Decade) +
  scale_x_continuous(breaks = seq(0, 200, by = 100))

Couleurs et échelles

Abordons désormais un élément-clé de ggplot2 : la manipulation des paramètres esthétiques. Précédemment, on n’a montré que deux de ces paramètres : x et y, les coordonnées du graphique. Mais ces paramètres peuvent aussi influencer la couleur des points de notre graphique comme le montre l’exemple suivant :

p + aes(color = ratio < 90)

Qu’a-t-on fait ici ? On a rajouté, au graphique stocké dans p, un paramètre esthétique qui détermine la couleur de ses points en fonction d’une inégalité, ratio < 90, qui est vraie quand le ratio Dette publique / PIB est inférieur au seuil fatidique de Reinhart et Rogoff, et fausse quand ce ratio dépasse ce seuil. Les couleurs des points correspondent aux couleurs par défaut de ggplot2, que l’on peut très facilement modifier avec scale_colour_brewer :

p + aes(color = ratio < 90) +
  scale_colour_brewer(palette = "Set1")

Ici, on a fait appel à la palette de couleur Set1 de l’éventail de couleurs ColorBrewer, qui est automatiquement disponible dans ggplot2, et qui est contenu dans l’extension RColorBrewer. La palette de couleurs que l’on a choisie affiche les points situés au-dessus du seuil fatidique de Reinhart et Rogoff en rouge, les autres en bleu.

Que peut-on dire, à ce stade, du seuil fatidique de Reinhart et Rogoff ? On peut observer qu’après la Seconde guerre mondiale, de nombreux pays sont déjà endettés au-delà de ce seuil, et dégagent déjà moins de croissance que les autres. Sur la base de cette trajectoire, de nombreux critiques de Reinhart et Rogoff ont fait remarquer que le raisonnement de Reinhart et Rogoff pose en réalité un sérieux problème d’inversion du rapport causal entre endettement et croissance au cours du temps.

Envisageons une nouvelle modification des paramètres graphiques. La légende du graphique, qui affiche FALSE et TRUE en fonction de l’inégalité ratio < 90, peut être déroutante. Clarifions un peu cette légende en supprimant son titre et en remplaçant les libellés (labels) FALSE et TRUE par leur signification :

p <- p + aes(color = ratio < 90) +
  scale_color_brewer("", palette = "Set1",
                     labels = c("ratio > 90", "ratio < 90"))

Dans le bloc de code ci-dessus, on a stocké l’ensemble de nos modifications dans l’objet p, sans l’afficher ; en effet, on souhaite encore procéder à une dernière modification, en rajoutant une régression locale à travers les points de chaque facette5. Après consultation de la documentation de ggplot2 ici et , on en arrive au code ci-dessous, où p produit le graphique précédent et geom_smooth produit la régression locale :

p + geom_smooth(method = "loess", se = FALSE,
                size = 1, color = "black")
`geom_smooth()` using formula 'y ~ x'

Le graphique permet d’évaluer de manière encore un peu plus précise l’argument de Reinhart et Rogoff, et en particulier la nature pas si fatidique du seuil de 90% du ratio “Dette publique / PIB”, qui sans être une bonne nouvelle pour l’économie, ne détermine pas fatidiquement la direction du taux de croissance : si c’était le cas, toutes les courbes du graphique ressembleraient à celles des années 2000. Autrement dit, l’argumentaire de Reinhart et Rogoff laisse clairement à désirer.

Utilisation des thèmes

Reprenons notre graphique de départ. On va, pour terminer cette démonstration, en construire une version imprimable en noir et blanc, ce qui signifie qu’au lieu d’utiliser des couleurs pour distinguer les points en-deçà et au-delà du seuil fatidique de Reinhart et Rogoff, on va utiliser une ligne verticale, produite par geom_vline et affichée en pointillés par le paramètre lty (linetype) :

ggplot(data = debt, aes(y = growth, x = ratio)) + 
  geom_point(color = "grey50") +
  geom_vline(xintercept = 90, lty = "dotted") +
  geom_smooth(method = "loess", size = 1, color = "black", se = FALSE) +
  scale_x_continuous(breaks = seq(0, 200, by = 100)) +
  facet_grid(. ~ Decade) +
  labs(y = "Taux de croissance du produit intérieur brut\n",
       x = "\nRatio dette publique / produit intérieur brut (%)",
       title = "Données Reinhart et Rogoff corrigées, 1946-2009\n") +
  theme_bw() +
  theme(strip.background = element_rect(fill = "grey90", color = "grey50"),
        strip.text = element_text(size = rel(1)),
        panel.grid = element_blank())
`geom_smooth()` using formula 'y ~ x'

Ce graphique utilise tous les éléments présentés dans ce chapitre, ainsi qu’une dernière nouveauté : l’utilisation d’un thème graphique différent du thème par défaut de ggplot2. Le thème par défaut, qui s’appelle theme_grey, est ici remplacé par un thème moins chargé, theme_bw (“black and white”), que l’on a modifié en y rajoutant quelques paramètres supplémentaires :

  • le paramètre strip.background détermine la couleur du rectangle contenant les titres des facettes, c’est-à-dire les décennies observées ;
  • le paramètre strip.text détermine la taille des titres des facettes, qui sont ici affichés dans la même taille de texte que le reste du texte ;
  • et le paramètre panel.grid supprime ici les guides du graphique grâce à l’élément vide element_blank, de manière à en alléger la lecture.

Ces différents réglages peuvent être sauvegardés de manière à créer des thèmes réutilisables, comme ceux de l’extension ggthemes, ce qui permet par exemple de créer un thème entièrement blanc dans lequel on peut ensuite projeter une carte, ou de produire une série de graphiques homogènes d’un point de vue esthétique.

Export des graphiques

Les graphiques produits par ggplot2 peuvent être sauvegardés manuellement, comme expliqué dans le chapitre Export des graphiques, ou programmatiquement. Pour sauvegarder le dernier graphique affiché par ggplot2 au format PNG, il suffit d’utiliser la fonction ggsave, qui permet d’en régler la taille (en pouces) et la résolution (en pixels par pouce ; 72 par défaut) :

ggsave("reinhart-rogoff.png", width = 11, height = 8)

De la même manière, pour sauvegarder n’importe quel graphique construit avec ggplot2 et stocké dans un objet, il suffit de préciser le nom de cet objet, comme ci-dessous, où l’on sauvegarde le graphique contenu dans l’objet p au format vectoriel PDF, qui préserve la netteté du texte et des autres éléments du graphique à n’importe quelle résolution d’affichage :

ggsave("reinhart-rogoff.pdf", plot = p,
       width = 11, height = 8)

Pour aller plus loin

Ce chapitre n’a pu faire la démonstration que d’une infime partie des manières d’utiliser ggplot2. En voici une dernière illustration, qui donne une idée des différents types de graphiques que l’extension permet de produire dès que l’on connaît les principaux éléments de sa syntaxe :

ggplot(data = debt, aes(x = ratio > 90, y = growth)) +
  geom_boxplot() +
  scale_x_discrete(labels = c("< 90", "90+")) +
  facet_grid(. ~ Decade) +
  labs(y = "Taux de croissance du produit intérieur brut\n",
       x = "\nRatio dette publique / produit intérieur brut (%)",
       title = "Données Reinhart et Rogoff corrigées, 1946-2009\n") +
  theme_linedraw() +
  theme(strip.text = element_text(size = rel(1)),
        panel.grid = element_blank())

Le code ci-dessus est somme toute très proche du code présenté dans le reste du texte, et en même temps, on a basculé de la visualisation sous forme de série temporelles à une visualisation par boxplots. Ces basculements sont très faciles à envisager dès que l’on maîtrise les principaux éléments de ggplot2, geom, scale et facet, et les paramètres labs et theme pour effectuer les finitions.

Ressources essentielles

Pour tout ce qui concerne l’utilisation de ggplot2, l’ouvrage de Wickham, en cours d’actualisation, est la ressource essentielle à consulter. L’ouvrage de Winston Chang, qui contient des dizaines d’exemples, le complète utilement, de même que la documentation en ligne de l’extension. Enfin, le site StackOverflow contient de très nombreuses questions/réponses sur les subtilités de sa syntaxe.

On trouve aussi très facilement, ailleurs sur Internet, des dizaines de tutorials et autres cheatsheets pour ggplot2, ici ou par exemple.

A noter également une gallerie de graphiques sous R avec de très nombreux exemples de graphique ggplot2 : http://www.r-graph-gallery.com/portfolio/ggplot2-package/

Extensions de ggplot2

Il faut signaler, pour terminer, quelques-unes des différentes extensions inspirées de ggplot2, dont la plupart sont encore en cours de développement, mais qui permettent d’ores et déjà de produire des centaines de types de graphiques différents, à partir d’une syntaxe graphique proche de celle présentée dans ce chapitre :


  1. Voir l’excellente documentation de l’extension et les autres ressources citées en fin de chapitre.

  2. Bien que l’on ait fait le choix de présenter l’extension ggplot2 plutôt que l’extension lattice, celle-ci reste un excellent choix pour la visualisation, notamment, de panels et de séries temporelles. On trouve de très beaux exemples d’utilisation de lattice en ligne, mais un peu moins de documentation, et beaucoup moins d’extensions, que pour ggplot2.

  3. Ce produit est mesuré en termes réels, de manière à ce que le calcul de sa croissance ne soit pas affecté par l’inflation.

  4. Plus précisément, cela introduit un retour à la ligne dans le titre de l’axe.

  5. La régression locale est une variante du calcul de la moyenne glissante (ou moyenne mobile) d’une courbe.

Graphiques univariés et bivariés avec ggplot2

Après avoir introduit l’extension ggplot2 au travers d’une étude de cas, nous reprenons ici les graphiques produits dans les chapitres statistique univariée et statistique bivariée et montrons comment les réaliser avec ggplot2.

Retour sur les bases de ggplot2

L’extension ggplot2 nécessite que les données du graphique soient sous la forme d’un tableau de données (data.frame) avec une ligne par observation et les différentes valeurs à représenter sous forme de variables du tableau.

Tous les graphiques avec ggplot2 suivent une même logique. En premier lieu, on appelera la fonction ggplot en lui passant en paramètre le fichier de données.

ggplot2 nomme esthétiques les différentes propriétés visuelles d’un graphique, à savoir l’axe des x (x), celui des y (y), la couleur des lignes (colour), celle de remplissage des polygones (fill), le type de lignes (linetype), etc. Une représentation graphique consiste donc à représenter chacune de nos variables d’intérêt selon une esthétique donnée. En second lieu, on appelera donc la fonction aes pour indiquer la correspondance entre les variables de notre fichier de données et les esthétiques du graphique.

A minima, il est nécessaire d’indiquer en troisième lieu une géométrie, autrement dit la manière dont les éléments seront représentés visuellement. À chaque géométrie corresponds une fonction commençant par geom_, par exemple geom_point pour dessiner des points, geom_line pour des lignes, geom_bar pour des barres ou encore geom_area pour des aires. Il existe de nombreuses géométries différentes, chacune prenant en compte certaines esthétiques, certaines étant requises pour cette géométrie et d’autres optionnelles. La liste des esthétiques prises en compte par chaque géométrie en indiquée dans l’aide en ligne de cette dernière.

Pour un document récapitulant les principales géométries et options de ggplot2, on pourra se référer à la Cheat Sheet officielle disponible à https://www.rstudio.com/wp-content/uploads/2015/03/ggplot2-cheatsheet.pdf. Une version en français est disponible à l’adresse http://thinkr.fr/pdf/ggplot2-french-cheatsheet.pdf.

ggplot2 reposant sur une syntaxe additive, la syntaxe de base d’un graphique sera donc de la forme :

ggplot(data) + aes(x = Var1, fill = Var2) + geom_bar()

De manière alternative, on peut également indiquer la correspondance entre variables et esthétiques comme deuxième argument de la fonction ggplot. Les deux syntaxes sont équivalentes.

ggplot(data, aes(x = Var1, fill = Var2)) + geom_bar()

Il est ensuite possible de personnaliser de nombreux éléments d’un graphique et notamment :

  • les étiquettes ou labs (titre, axes, légendes) avec ggtitle, xlab, ylab ou encore la fonction plus générique labs ;
  • les échelles (scales) des différentes esthétiques avec les fonctions commençant par scale_ ;
  • les facettes (facets) avec les fonctions commençant par facet_ ;
  • le système de coordonnées avec les fonctions commençant par coord_ ;
  • la légende (guides) avec les fonctions commençant par guide_ ;
  • le thème du graphiques (mise en forme des différents éléments) avec theme.

Ces différents éléments seront abordés plus en détails dans le chapitre avancé sur ggplot2. Dans la suite de ce chapitre, nous nous focaliserons sur les graphiques et options de base.

Grammaire des graphiques de ggplot2

Préparons les données des exemples et chargeons ggplot2 :

library(questionr)
library(ggplot2)
data("hdv2003")
d <- hdv2003

Histogramme

Pour un histogramme, on aura recours à la géométrie geom_histogram. Si l’on a une observation par ligne dans le fichier de données, l’histogramme s’obtient simplement en associant la variable d’intérêt à l’esthétique x. Notez la syntaxe de aes : le nom des variables est indiqué directement, sans guillemets.

ggplot(d) +
  aes(x = heures.tv) +
  geom_histogram() +
  ggtitle("Nombres d'heures passées devant la télévision") +
  xlab("Heures") +
  ylab("Effectifs")
Un histogramme

On peut personnaliser la couleur de remplissage des rectangles en indiduant une valeur fixe pour l’esthétique fill dans l’appel de geom_histogram (et non via la fonction aes puisqu’il ne s’agit pas d’une variable du tableau de données). L’esthétique colour permet de spécifier la couleur du trait des rectangles. Enfin, le paramètre binwidth permet de spécifier la largeur des barres.

ggplot(d) +
  aes(x = heures.tv) +
  geom_histogram(fill ="orange", colour = "black", binwidth = 2) +
  ggtitle("Nombres d'heures passées devant la télévision") +
  xlab("Heures") +
  ylab("Effectifs")
Un histogramme en couleur

Comme avec la fonction hist, on peut personnaliser les classes avec l’argument breaks.

ggplot(d) +
  aes(x = heures.tv) +
  geom_histogram(fill ="orange", colour = "black", breaks = c(0, 1, 4, 9, 12)) +
  ggtitle("Nombres d'heures passées devant la télévision") +
  xlab("Heures") +
  ylab("Effectifs")
Un histogramme avec classes personnalisées

On peut ajouter à l’axe des x des tirets représentant la position des observations à l’aide de geom_rug.

ggplot(d) +
  aes(x = heures.tv) +
  geom_histogram(fill ="orange", colour = "black", binwidth = 2) +
  geom_rug() +
  ggtitle("Nombres d'heures passées devant la télévision") +
  xlab("Heures") +
  ylab("Effectifs")
Un histogramme avec geom_rug()

Densité et répartition cumulée

Une courbe de densité s’obtient aisément avec la géométrie geom_density.

ggplot(d) +
  aes(x = heures.tv) +
  geom_density() +
  ggtitle("Nombres d'heures passées devant la télévision") +
  xlab("Heures") +
  ylab("Densité")
Courbe de densité

On peut personnaliser la fenêtre d’ajustement avec l’argument adjust.

ggplot(d) +
  aes(x = heures.tv) +
  geom_density(adjust = 1.5) +
  ggtitle("Nombres d'heures passées devant la télévision") +
  xlab("Heures") +
  ylab("Densité")
Courbe de densité avec fenêtre d’ajustement personnalisée

Pour la fonction de répartition empirique ou empirical cumulative distribution function en anglais, on utilisera la statistique stat_ecdf. Au passage, on notera qu’il est possible d’ajouter une couche à un graphique en appelant soit une géométrie, soit une statistique.

ggplot(d) +
  aes(x = heures.tv) +
  stat_ecdf() +
  xlab("Heures") +
  ylab("Fonction de répartition cumulée")
Fonction de répartition empirique cumulée

Boîtes à moustaches (et représentations associées)

La géométrie geom_boxplot nécessite a minima deux esthétiques : x et y. Pour représenter une variable quantitative selon une variable catégorielle, on fera donc :

ggplot(d) +
  aes(x = hard.rock, y = age) +
  geom_boxplot() +
  xlab("Ecoute du hard rock") +
  ylab("Âge") +
  ggtitle("Répartition par âge selon que l'on écoute du hard rock ou non")
Boîtes à moustache

Lorsque l’on souhaite représenter une seule variable quantitative (statistique univariée), on passera alors une constante à l’esthétique x.

ggplot(d) +
  aes(x = "Nombre d'heures passées devant la télévision", y = heures.tv) +
  geom_boxplot() +
  xlab("") +
  ylab("Heures quotidiennes")
Boîte à moustache (une seule variable)

Une représentation alternative aux boîtes à moustaches ou boxplots sont les graphiques en violon ou violin plots, qui représentent la densité de distribution. Ils s’obtiennent avec la géométrie geom_violin.

ggplot(d) +
  aes(x = hard.rock, y = age) +
  geom_violin() +
  xlab("Ecoute du hard rock") +
  ylab("Âge") +
  ggtitle("Répartition par âge selon que l'on écoute du hard rock ou non")
Graphiques en violon ou violin plot

Les boîtes à moustache peuvent parfois être trompeuses car ne représentant qu’imparfaitement la distribution d’une variable quantitative. Voir par exemple The boxplot and its pitfalls sur https://www.data-to-viz.com.

Les graphique de pirates ou pirateplot sont une visualisation alternative qui combinent :

  • un nuage de points représentant les données brutes ;
  • une barre verticale représentant la moyenne ;
  • un rectangle traduisant l’intervalle de confiance de cette moyenne ;
  • un violon indiquant la distribution.

L’extension ggpirate fournit une géométrie geom_pirate pour ggplot2. Cette extension n’étant disponible que sur GitHub, on l’installera avec la commande :

devtools::install_github("mikabr/ggpirate")
library(ggpirate)
ggplot(d) +
  aes(x = hard.rock, y = age, colour = hard.rock, fill = hard.rock)  +
  geom_pirate() +
  xlab("Ecoute du hard rock") +
  ylab("Âge") +
  ggtitle("Répartition par âge selon que l'on écoute du hard rock ou non") +
  theme_minimal() +
  theme(panel.grid.minor = element_blank())
No summary function supplied, defaulting to `mean_se()`
No summary function supplied, defaulting to `mean_se()`
Graphiques de pirates ou pirateplot

Diagramme en bâtons

Un diagramme en bâtons s’obtient avec la géométrie geom_bar.

ggplot(d) +
  aes(x = freres.soeurs) +
  geom_bar() +
  xlab("Nombre de frères et soeurs") +
  ylab("Effectifs")
Diagramme en bâtons

La largeur des barres par défaut est de 0,9. Dès lors, le graphique ressemble plus à un histogramme qu’à un diagramme en bâtons. On peut personnaliser ce paramètre avec l’argument width.

ggplot(d) +
  aes(x = freres.soeurs) +
  geom_bar(width = .2) +
  xlab("Nombre de frères et soeurs") +
  ylab("Effectifs")
Diagramme en bâtons avec ajustement de la largeur des barres

Nuage de points

Un nuage de points se représente facilement avec la géométrie geom_point.

ggplot(d) +
  aes(x = age, y = heures.tv) +
  geom_point() +
  xlab("Âge") +
  ylab("Heures quotidiennes de télévision")
Nuage de points

On pourra personnaliser la couleur des points avec colour et le niveau de transparence avec alpha.

ggplot(d) +
  aes(x = age, y = heures.tv) +
  geom_point(colour = "red", alpha = .2) +
  xlab("Âge") +
  ylab("Heures quotidiennes de télévision")
Nuage de points semi-transparents

Une variante à geom_point est geom_count qui compte le nombre d’observations situées sur le même point et dessine des points dont la taille est proportionnelle à ce nombre d’observations.

ggplot(d) +
  aes(x = age, y = heures.tv) +
  geom_count(colour = "red", alpha = .2) +
  xlab("Âge") +
  ylab("Heures quotidiennes de télévision") +
  labs(size = "effectifs")
Nuage de points de taille proportionnelle au nombre d’observations

Pour représenter une troisième variable quantitative, on pourra faire varier la taille des points avec l’esthétique size. Pour une variable qualitative, on pourra faire varier la couleur avec colour. Pour faciliter la lecture, on positionnera la légende en bas du graphique, en modifiant l’argument legend.position via la fonction theme.

data("rp99")
rp99$prop.proprio <- 0
rp99[rp99$proprio >= mean(rp99$proprio), ]$prop.proprio <- 1
rp99$prop.proprio <- factor(rp99$prop.proprio, 0:1, c("non", "oui"))
ggplot(rp99) +
  aes(x = dipl.aucun, y = tx.chom, size = pop.tot, colour = prop.proprio) +
  geom_point(alpha = .5) +
  xlab("% sans diplôme") +
  ylab("Taux de chômage") +
  labs(size = "Population totale", colour = "Proportion de propriétaires supérieure à la moyenne") +
  theme(
    legend.position = "bottom",
    legend.box = "vertical"
  )
Nuage de points proportionnels

geom_smooth permets d’ajouter au graphique une moyenne mobile du nuage de points avec son intervalle de confiance. Notez que l’on ajoute geom_smooth au graphique avant geom_point puisque l’ordre dans lequel sont affichées les différentes couches du graphique dépend de l’ordre dans lequel elles ont été ajoutées. Dans cet exemple, nous souhaitons afficher les points au-dessus de la moyenne mobile.

ggplot(rp99) +
  aes(x = dipl.sup, y = cadres) +
  geom_smooth() +
  geom_point() +
  xlab("% de diplômés du supérieur") +
  ylab("% de cadres")
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
Nuage de points avec moyenne mobile

Si l’on préfère afficher plutôt la droite de régression, on indiquera à geom_smooth l’agument method = "lm".

ggplot(rp99) +
  aes(x = dipl.sup, y = cadres) +
  geom_smooth(method = "lm") +
  geom_point() +
  xlab("% de diplômés du supérieur") +
  ylab("% de cadres")
`geom_smooth()` using formula 'y ~ x'
Nuage de points avec droite de régression linéaire

Matrice de nuages de points et matrice de corrélation

ggplot2 ne fournit pas de fonction native pour la réalisation d’une matrice de nuages de points. Cependant, il existe plusieurs extensions permettant d’étendre ggplot2. Parmi celles-ci, l’extension GGally propose une fonction ggpairs correspondant exactement à notre besoin.

library(GGally)
ggpairs(rp99[, c("proprio", "hlm", "locataire", "maison")])
Matrice de nuages de points

ggpairs accepte même des variables catégorielles ainsi que des esthétiques supplémentaires, offrant ainsi plus de possibilités que la fonction pairs1.

ggpairs(rp99[, c("hlm", "locataire", "maison", "prop.proprio")], aes(colour = prop.proprio))
Matrice de nuages de points avec variables catégorielles

GGally propose également une fonction ggcorr permettant d’afficher une matrice de corrélation entre variables quantitatives2.

ggcorr(rp99)
Matrice de corrélarion

Estimation locale de densité (et représentations associées)

On peut aisément représenter une estimation locale de densité avec la géométrie geom_density_2d.

ggplot(d) +
  aes(x = age, y = heures.tv) +
  geom_density_2d() +
  xlab("Âge") +
  ylab("Heures quotidiennes de télévision")
Estimation locale de densité (contours)

Par défaut, le résultat est représenté sous forme de contours. Pour obtenir une représentation avec des polygones, on appelera la statistique stat_density_2d en forçant la géométrie.

ggplot(d) +
  aes(x = age, y = heures.tv, fill = after_stat(level)) +
  stat_density_2d(geom = "polygon") +
  xlab("Âge") +
  ylab("Heures quotidiennes de télévision") +
  labs(fill = "Densité")
Estimation locale de densité (contours)

ggplot2 propose également deux géométries, geom_bin2d et geom_hex, permettant d’effectuer à un comptage des effectifs en deux dimensions.

ggplot(d) +
  aes(x = age, y = heures.tv) +
  geom_bin2d() +
  xlab("Âge") +
  ylab("Heures quotidiennes de télévision") +
  labs(fill = "Effectifs")
Effectifs en deux dimensions
ggplot(d) +
  aes(x = age, y = heures.tv) +
  geom_hex() +
  xlab("Âge") +
  ylab("Heures quotidiennes de télévision") +
  labs(fill = "Effectifs")
Effectifs en deux dimensions (hexagones)

Pour reproduire à l’identique l’exemple donné dans le chapitre statistique bivariée, on aura besoin de la méthode tidy de l’extension broom afin de transformer le résultat de kde2d en un tableau de données exploitables par ggplot2. tidy est une méthode générique permettant de transformer un grand nombre d’objets (et en particulier les résultats d’un modèle) en un tableau de données exploitable by ggplot2.

library(MASS)
tmp <- d[, c("age", "heures.tv")]
tmp <- tmp[complete.cases(tmp), ]
library(broom)
tmp <- tidy(kde2d(tmp$age, tmp$heures.tv))
str(tmp)
tibble [625 x 3] (S3: tbl_df/tbl/data.frame)
 $ x: num [1:625] 18 18 18 18 18 18 18 18 18 18 ...
 $ y: chr [1:625] "0" "0.5" "1" "1.5" ...
 $ z: num [1:625] 0.00147 0.00148 0.00136 0.00137 0.00238 ...
ggplot(tmp) + 
  aes(x = x, y = y, fill = z) +
  geom_raster(interpolate = TRUE) +
  scale_fill_gradientn(colors = terrain.colors(14)) +
  labs(x = "Âge", y = "Heures de TV", fill = "Densité")

Diagramme de Cleveland

Pour un diagramme de Cleveland, on aura recours à la géométrie geom_point. Cependant, il faudra lui préciser que l’on souhaite utiliser la statistique stat_count afin que les effectifs soient calculés pour chaque valeur de x.

ggplot(d) +
  aes(x = clso) +
  geom_point(stat = "count") +
  xlab("Sentiment d'appartenance à une classe sociale") +
  ylab("Effectifs")
Diagramme de Cleveland

Une alternative, notamment si l’on souhaite un diagramme de Cleveland ordonné, consiste à calculer les effectifs de chaque modalité en amont. ggplot2 ayant besoin d’un tableau de données en entrée, nous calculerons notre tableau de fréquences avec xtabs et le transformerons en tableau de données avec as.data.frame. Pour que les niveaux de qualifaction soient représentés selon leur effectif, il est nécessaire d’ordonner les étiquettes du facteur de manière adéquate. Enfin, nous utiliserons coord_flip pour intervertir l’axe des x et celui des y.

tab <- as.data.frame(xtabs(~qualif, d))
tab$qualif <- factor(tab$qualif, levels = tab$qualif[order(tab$Freq)])
str(tab)
'data.frame':   7 obs. of  2 variables:
 $ qualif: Factor w/ 7 levels "Autre","Technicien",..: 4 6 2 3 5 7 1
 $ Freq  : int  203 292 86 160 260 594 58
ggplot(tab) +
  aes(x = qualif, y = Freq) +
  geom_point() +
  xlab("Niveau de qualification") +
  ylab("Effectifs") +
  coord_flip()
Diagramme de Cleveland ordonné

L’extension ggalt propose quelques géométries supplémentaires pour ggplot2. L’une d’elles dite en sucettes (geom_lollipop) propose une représentation graphique au croisement entre un diagramme en bâtons et un diagramme de Cleveland.

library(ggalt)
ggplot(tab) +
  aes(x = qualif, y = Freq) +
  geom_lollipop() +
  xlab("Niveau de qualification") +
  ylab("Effectifs") +
  coord_flip()

Diagrammes en barres

Un diagramme en barres se construit avec la géométrie geom_bar.

d$qualreg <- as.character(d$qualif)
d$qualreg[d$qualif %in% c("Ouvrier specialise", "Ouvrier qualifie")] <- "Ouvrier"
d$qualreg[d$qualif %in% c("Profession intermediaire", 
  "Technicien")] <- "Intermediaire"
ggplot(d) +
  aes(x = qualreg, fill = sport) +
  geom_bar() +
  xlab("CSP") +
  ylab("Effectifs") +
  labs(fill = "Pratique du sport")
Diagramme en barres

On peut modifier la position des barres avec le paramètre position.

ggplot(d) +
  aes(x = qualreg, fill = sport) +
  geom_bar(position = "dodge") +
  xlab("CSP") +
  ylab("Effectifs") +
  labs(fill = "Pratique du sport")
Diagramme en barres côte à côte

Pour des barres cumulées, on aura recours à position = "fill". Pour que les étiquettes de l’axe des y soient représentées sous forme de pourcentages (i.e. 25% au lieu de 0.25), on aura recours à la fonction percent de l’extension scales, qui sera transmise à ggplot2 via scale_y_continuous.

library(scales)
ggplot(d) +
  aes(x = qualreg, fill = sport) +
  geom_bar(position = "fill") +
  xlab("CSP") +
  ylab("Proportion") +
  labs(fill = "Pratique du sport") +
  scale_y_continuous(labels = percent)
Diagramme en barres cumulées

Ajouter des étiquettes sur un diagramme en barre

Il est facile d’ajouter des étiquettes en ayant recours à geom_text, à condition de lui passer les bon paramètres.

Tout d’abord, il faudra préciser stat = "count" pour indiquer que l’on souhaite utiliser la statistique stat_count qui est celle utilisé par défaut par geom_bar. C’est elle qui permets de compter le nombre d’observation.

Il faut ensuite utiliser l’esthétique label pour indiquer ce que l’on souhaite afficher comme étiquettes. after_stat(count) permets d’accéder à la variable calculée par stat_count.

Enfin, il faut indiquer la position verticale avec position_stack. En précisant un ajustement de vertical de 0.5, on indique que l’on souhaite positionner l’étiquette au milieu.

ggplot(d) +
  aes(x = qualreg, fill = sport) +
  geom_bar() +
  geom_text(aes(label = after_stat(count)), stat = "count", position = position_stack(.5)) +
  xlab("CSP") +
  ylab("Effectifs") +
  labs(fill = "Pratique du sport")

Pour un graphique en barre cumulées, on peut utiliser de manière similaire position_fill.

ggplot(d) +
  aes(x = qualreg, fill = sport) +
  geom_bar(position = "fill") +
  geom_text(aes(label = after_stat(count)), stat = "count", position = position_fill(.5)) +
  xlab("CSP") +
  ylab("Proportion") +
  labs(fill = "Pratique du sport") +
  scale_y_continuous(labels = percent)

On ne peut afficher directement les proportions avec stat_count. Cependant, l’extension GGally fournit une statistique stat_prop dont le dénominateur peut être personnalisé via l’esthétique by (attention : l’esthétique attendue doit impérativement être un facteur).

library(GGally)
d$qualreg <- forcats::fct_explicit_na(factor(d$qualreg))
ggplot(d) +
  aes(x = qualreg, fill = sport) +
  geom_bar(position = "fill") +
  geom_text(aes(by = qualreg), stat = "prop", position = position_fill(.5)) +
  xlab("CSP") +
  ylab("Proportion") +
  labs(fill = "Pratique du sport") +
  scale_y_continuous(labels = scales::percent)

On peut aussi comparer facilement deux distributions, ici la proportion de chaque niveau de qualification au sein chaque sexe.

p <- ggplot(d) +
  aes(
    x = qualreg, fill = sexe, by = sexe, y = after_stat(prop),
    label = scales::percent(after_stat(prop), accuracy = 1), 
  ) +
  geom_bar(stat = "prop", position = position_dodge(.9)) +
  geom_text(
    aes(y = after_stat(prop) - .005), stat = "prop", 
    position = position_dodge(.9), vjust = "top"
  ) +
  scale_y_continuous(labels = percent)
p

Il est possible d’alléger le graphique en retirant des éléments superflus.

p + 
  theme_light() +
  xlab("") +
  ylab("") +
  labs(fill = "") +
  ggtitle("Distribution de la population selon le niveau de qualification, par sexe") +
  theme(
    panel.grid = element_blank(),
    panel.border = element_blank(),
    axis.text.y = element_blank(),
    axis.ticks = element_blank(),
    legend.position = "top"
  ) +
  scale_fill_brewer()

Comparer plusieurs variables discrètes et/ou continues

L’extension GGally, déjà évoquée, fournit également deux fonctions utiles pour comparer plusieurs variables discrètes (et/ou continues) : ggbivariate et ggtable.

ggbivariate produit des graphiques en barre pour deux variables discrètes et des boites à moustache lorsque l’on compare une variable discrète avec une variable continue.

library(GGally)
ggbivariate(data = d, outcome = "sport", explanatory = c("sexe", "cuisine", "nivetud", "age"))
Warning: Removed 112 rows containing non-finite values
(stat_prop).

ggtable quant à elle affiche un tableau croisé avec le nombre d’observations pour deux variables discrètes et les médianes avec l’intervalle interquartile pour une variable discrète croisée avec une variable continue.

ggtable(data = d, columnsX = "sport", columnsY = c("sexe", "cuisine", "nivetud", "age"))

Il est possible de remplacer les effectifs par les pourcentages en ligne et de colorier les cellules en fonction des résidus du Chi² qui permettent de visualiser les cellules du tableau sur- ou sous-représentées.

ggtable(
  data = d, 
  columnsX = "sport", 
  columnsY = c("sexe", "cuisine", "nivetud"),
  cells = "row.prop",
  fill = "std.resid",
  legend = 1
) + labs(fill = "Résidus\ndu Chi²")

Pour plus de possibilités de personnalisation, voir la fonction ggduo de GGally.

Graphe en mosaïque

Il n’y a pas, à ce jour, d’implémentation officielle des graphiques en mosaïque sous ggplot2. On pourra néanmoins se référer à l’extension ggmosaic et sa fonction geom_mosaic3.

library(ggmosaic)
levels(d$sport) <- c("Ne fait pas de sport", "Pratique un sport")
levels(d$cuisine) <- c("Ne cuisine pas", "Cuisine")
levels(d$sexe) <- c("H", "F")

ggplot(data = d) +
  geom_mosaic(aes(x = product(sport, cuisine), fill = sexe, na.rm = TRUE)) +
  xlab("") + ylab("") +
  theme(legend.position = "bottom")  
Graphique en mosaïque

Données labellisées et ggplot2

ggplot2 tient compte du type des variables, attendant à ce que les variables catégorielles soient présentées sous forme de facteurs. Si l’on utilise des données labellisées (voir le chapitre dédié), nos variables catégorielles seront stockées sous la forme d’un vecteur numérique avec des étiquettes. Il sera donc nécessaire de convertir ces variables en facteurs, tout simplement avec la fonction to_factor de l’extension labelled qui pourra utiliser les étiquettes de valeurs comme modalités du facteur.

Exporter les graphiques obtenus

Les graphiques produits par ggplot2 peuvent être sauvegardés manuellement, comme expliqué dans le chapitre Export des graphiques, ou programmatiquement. Pour sauvegarder le dernier graphique affiché par ggplot2 au format PNG, il suffit d’utiliser la fonction ggsave, qui permet d’en régler la taille (en pouces) et la résolution (en pixels par pouce ; 72 par défaut) :

ggsave("mon_graphique.png", width = 11, height = 8)

De la même manière, pour sauvegarder n’importe quel graphique construit avec ggplot2 et stocké dans un objet, il suffit de préciser le nom de cet objet, comme ci-dessous, où l’on sauvegarde le graphique contenu dans l’objet p au format vectoriel PDF, qui préserve la netteté du texte et des autres éléments du graphique à n’importe quelle résolution d’affichage :

ggsave("mon_graphique.pdf", plot = p,
       width = 11, height = 8)

  1. Pour plus de détails, on pourra lire https://tgmstat.wordpress.com/2013/11/13/plot-matrix-with-the-r-package-ggally/.

  2. Pour une présentation détaillée de cette fonction et de ses options, voir https://briatte.github.io/ggcorr/.

  3. Pour information, une première implémentation expérimentale avait été proposée avec l’extension productplots, voir https://github.com/hadley/productplots et http://vita.had.co.nz/papers/prodplots.html

Données pondérées

S’il est tout à fait possible de travailler avec des données pondérées sous R, cette fonctionnalité n’est pas aussi bien intégrée que dans la plupart des autres logiciels de traitement statistique. En particulier, il y a plusieurs manières possibles de gérer la pondération. Cependant, lorsque l’on doit également prendre un compte un plan d’échantillonnage complexe (voir section dédiée ci-après), R fournit tous les outils nécessaires, alors que dans la plupart des logiciels propriétaires, il faut disposer d’une extension adéquate, pas toujours vendue de base avec le logiciel.

Dans ce qui suit, on utilisera le jeu de données tiré de l’enquête Histoire de vie et notamment sa variable de pondération poids1.

library(questionr)
data(hdv2003)
d <- hdv2003
range(d$poids)
[1]    78.07834 31092.14132

Options de certaines fonctions

Tout d’abord, certaines fonctions de R acceptent en argument un vecteur permettant de pondérer les observations (l’option est en général nommée weights ou row.w). C’est le cas par exemple des méthodes d’estimation de modèles linéaires2 (lm) ou de modèles linéaires généralisés 3 (glm) ou dans les analyses de correspondances4 des extensions ade4 ou FactoMineR.

Par contre cette option n’est pas présente dans les fonctions de base comme mean, var, table ou chisq.test.

Données pondérées avec l’extension survey

L’extension survey est spécialement dédiée au traitement d’enquêtes ayant des techniques d’échantillonnage et de pondération potentiellement très complexes.

L’extension s’installe comme la plupart des autres :

install.packages("survey")

Le site officiel (en anglais) comporte beaucoup d’informations, mais pas forcément très accessibles :
http://r-survey.r-forge.r-project.org/.

Pour utiliser les fonctionnalités de l’extension, on doit d’abord définir le plan d’échantillonnage ou design de notre enquête, c’est-à-dire indiquer quel type de pondération nous souhaitons lui appliquer.

Dans un premier temps, nous utiliserons le plan d’échantillonnage le plus simple, avec une variable de pondération déjà calculée. Pour d’autres types de plan d’échantillonnage, voir la chapitre sur les plans d’échantillonnage complexes.

Ceci se fait à l’aide de la fonction svydesign :

library(survey)
dw <- svydesign(ids = ~1, data = d, weights = ~ d$poids)

Cette fonction crée un nouvel objet, que nous avons nommé dw. Cet objet n’est pas à proprement parler un tableau de données, mais plutôt un tableau de données plus une méthode de pondération. dw et d sont des objets distincts, les opérations effectuées sur l’un n’ont pas d’influence sur l’autre. On peut cependant retrouver le contenu de d depuis dw en utilisant dw$variables :

str(d$age)
 int [1:2000] 28 23 59 34 71 35 60 47 20 28 ...
str(dw$variables$age)
 int [1:2000] 28 23 59 34 71 35 60 47 20 28 ...

Lorsque notre plan d’échantillonnage est déclaré, on peut lui appliquer une série de fonctions permettant d’effectuer diverses opérations statistiques en tenant compte de la pondération. On citera notamment :

  • svymean, svyvar, svytotal, svyquantile : statistiques univariées (moyenne, variance, total, quantiles)
  • svytable : tri à plat et tableau croisé
  • svychisq : test du ²
  • svyby : statistiques selon un facteur
  • svyttest : test t de Student de comparaison de moyennes
  • svyciprop : intervalle de confiance d’une proportion
  • svyglm : modèles linéaires généralisés (dont régression logistique)
  • svyplot, svyhist, svyboxplot : fonctions graphiques

D’autres fonctions sont disponibles, comme svyratio, mais elles ne seront pas abordées ici.

Pour ne rien arranger, ces fonctions prennent leurs arguments sous forme de formules5, c’est-à-dire pas de la manière habituelle. En général l’appel de fonction se fait en spécifiant d’abord les variables d’intérêt sous forme de formule, puis l’objet survey.design.

Voyons tout de suite quelques exemples6 :

svymean(~age, dw)
      mean     SE
age 46.347 0.5284
svyquantile(~age, dw, quantile = c(0.25, 0.5, 0.75), ci = TRUE)
$quantiles
    0.25 0.5 0.75
age   31  45   60

$CIs
, , age

       0.25 0.5 0.75
(lower   30  43   58
upper)   32  47   62
svyvar(~heures.tv, dw, na.rm = TRUE)
          variance     SE
heures.tv   2.9886 0.1836

Les tris à plat se déclarent en passant comme argument le nom de la variable précédé d’un tilde (~), tandis que les tableaux croisés utilisent les noms des deux variables séparés par un signe plus (+) et précédés par un tilde (~).

svytable(~sexe, dw)
sexe
  Homme   Femme 
5149382 5921844 
svytable(~ sexe + clso, dw)
       clso
sexe           Oui        Non Ne sait pas
  Homme 2658744.04 2418187.64    72450.75
  Femme 2602031.76 3242389.36    77422.79

La fonction freq peut être utilisée si on lui passe en argument non pas la variable elle-même, mais son tri à plat obtenu avec svytable :

tab <- svytable(~peche.chasse, dw)
freq(tab, total = TRUE)

On peut également récupérer le tableau issu de svytable dans un objet et le réutiliser ensuite comme n’importe quel tableau croisé :

tab <- svytable(~ sexe + clso, dw)
tab
       clso
sexe           Oui        Non Ne sait pas
  Homme 2658744.04 2418187.64    72450.75
  Femme 2602031.76 3242389.36    77422.79

Les fonctions lprop et cprop de questionr sont donc tout à fait compatibles avec l’utilisation de survey.

lprop(tab)
          clso
sexe       Oui   Non   Ne sait pas Total
  Homme     51.6  47.0   1.4       100.0
  Femme     43.9  54.8   1.3       100.0
  Ensemble  47.5  51.1   1.4       100.0

Le principe de la fonction svyby est similaire à celui de tapply7. Elle permet de calculer des statistiques selon plusieurs sous-groupes définis par un facteur. Par exemple :

svyby(~age, ~sexe, dw, svymean)

gtsummary et survey

L’extension gtsummary fournit une fonction tbl_svysummary, similaire à tbl_summary, mais adaptée aux objets survey.

library(gtsummary)
theme_gtsummary_language("fr", decimal.mark = ",", big.mark = " ")
Setting `language: fr` theme
dw %>% tbl_svysummary(include = c("age", "sexe", "clso", "peche.chasse"))
Caractéristique N = 11 071 2261
age 45 (31 – 60)
sexe
Homme 5 149 382 (47%)
Femme 5 921 844 (53%)
clso
Oui 5 260 776 (48%)
Non 5 660 577 (51%)
Ne sait pas 149 874 (1,4%)
peche.chasse
Non 9 716 683 (88%)
Oui 1 354 544 (12%)

1 Statistique présentée: Médiane (EI); n (%)

dw %>%
  tbl_svysummary(
    include = c("age", "sexe", "clso", "peche.chasse"),
    by = "sexe"
  ) %>%
  add_overall(last = TRUE) %>%
  add_p()
Caractéristique Homme, N = 5 149 3821 Femme, N = 5 921 8441 Total, N = 11 071 2261 p-value2
age 44 (30 – 59) 45 (32 – 61) 45 (31 – 60) 0,067
clso 0,036
Oui 2 658 744 (52%) 2 602 032 (44%) 5 260 776 (48%)
Non 2 418 188 (47%) 3 242 389 (55%) 5 660 577 (51%)
Ne sait pas 72 451 (1,4%) 77 423 (1,3%) 149 874 (1,4%)
peche.chasse <0,001
Non 4 101 242 (80%) 5 615 441 (95%) 9 716 683 (88%)
Oui 1 048 141 (20%) 306 403 (5,2%) 1 354 544 (12%)

1 Statistique présentée: Médiane (EI); n (%)

2 Test statistique réalisé: Wilcoxon rank-sum test for complex survey samples; chi-squared test with Rao & Scott's second-order correction

Graphiques natifs avec survey

survey est également capable de produire des graphiques à partir des données pondérées. Quelques exemples :

par(mfrow = c(2, 2))
svyplot(~ age + heures.tv, dw, col = "red", main = "Bubble plot")
svyhist(~heures.tv, dw, col = "peachpuff", main = "Histogramme")
svyboxplot(age ~ 1, dw, main = "Boxplot simple", ylab = "Âge")
svyboxplot(age ~ sexe, dw, main = "Boxplot double", ylab = "Âge", xlab = "Sexe")
Fonctions graphiques de l’extension survey

Graphiques ggplot2

ggplot2 accepte une esthétique weight pour indiquer des poids à prendre en compte dans les différents graphiques. La fonction weights permets justement de récupérer les poids d’un objet survey. La fonction ggplot n’accepte pas d’objet survey mais a besoin d’un tableau de données. Ce dernier peut être récupéré avec $variables.

library(ggplot2)
ggplot(dw$variables) +
  aes(weight = weights(dw), x = sexe, fill = clso) +
  geom_bar(position = "fill")

ATTENTION : les graphiques obtenus ne sont corrects qu’à la condition que seuls les poids soient nécessaires pour les construire, ce qui est le cas d’un nuage de points ou d’un diagramme en barres. Par contre, si le calcul du graphique implique le calcul de variance, la représentation sera incorrecte. Par exemple, avec geom_smooth, les aires de confiance affichées ne prendront pas correctement en compte le plan d’échantillonnage.

L’extenstion JLutils propose une fonction ggsurvey pour faciliter les choses. Elle prend un objet survey, extrait le tableau de données et les poids, associe les poids à l’esthétique correspondante et appelle ggplot.

library(JLutils)
ggsurvey(dw) +
  aes(x = sexe, fill = clso) +
  geom_bar(position = "fill")

JLutils n’est disponible que sur GitHub. Pour l’installer, on pourra utiliser la commande suivante :

if (!require(devtools)) {
  install.packages("devtools")
  library(devtools)
}
install_github("larmarange/JLutils")

Extraire un sous-échantillon

Si l’on souhaite travailler sur un sous-échantillon tout en gardant les informations d’échantillonnage, on utilisera la fonction subset présentée en détail dans le chapitre Sous-ensembles.

sous <- subset(dw, sexe == "Femme" & age >= 40)

Modèles logistiques

Pour réaliser des modèles logistiques (binaires, multinomiaux ou ordinaux) avec prise en compte d’un plan d’échantillonnage, on pourra se référer à la sous-section dédiée du chapitre Régression logistique.

dplyr et survey

L’extension srvyr vise à permettre d’utiliser les verbes de dplyr avec survey. Le fonctionnement de cette extension est expliqué dans une vignette dédiée : https://cran.r-project.org/web/packages/srvyr/vignettes/srvyr-vs-survey.html.

Conclusion

Si, la gestion de la pondération sous R n’est sans doute pas ce qui se fait de plus pratique et de plus simple, on pourra quand même donner les conseils suivants :

  • utiliser les options de pondération des fonctions usuelles ou les fonctions d’extensions comme questionr pour les cas les plus simples ;
  • si on utilise survey, effectuer autant que possible tous les recodages et manipulations sur les données non pondérées ;
  • une fois les recodages effectués, on déclare le design et on fait les analyses en tenant compte de la pondération ;
  • surtout ne jamais modifier les variables du design. Toujours effectuer recodages et manipulations sur les données non pondérées, puis redéclarer le design pour que les mises à jour effectuées soient disponibles pour l’analyse.

  1. On notera que cette variable est utilisée à titre purement illustratif. Le jeu de données étant un extrait d’enquête et la variable de pondération n’ayant pas été recalculée, elle n’a ici à proprement parler aucun sens.

  2. Voir le chapitre régression linéaire.

  3. Voir le chapitre sur la régression logistique.

  4. Voir le chapitre dédié à l’analyse des correspondances.

  5. Pour plus de détails sur les formules, voir le chapitre dédié.

  6. Pour d’autres exemples, voir http://www.ats.ucla.edu/stat/r/faq/svy_r_oscluster.htm (en anglais).

  7. La fonction tapply est présentée plus en détails dans le chapitre Manipulation de données.

Intervalles de confiance

Nous utiliserons dans ce chapitre les données de l’enquête Histoire de vie 2003 fournies avec l’extension questionr.

library(questionr)
data("hdv2003")
d <- hdv2003

Intervalle de confiance d’une moyenne

L’intervalle de confiance d’une moyenne peut être calculé avec la fonction t.test (fonction qui permet également de réaliser un test t de Student comme nous le verrons dans le chapitre dédié aux comparaisons de moyennes) :

t.test(d$heures.tv)

    One Sample t-test

data:  d$heures.tv
t = 56.505, df = 1994, p-value < 2.2e-16
alternative hypothesis: true mean is not equal to 0
95 percent confidence interval:
 2.168593 2.324540
sample estimates:
mean of x 
 2.246566 

Le niveau de confiance peut être précisé via l’argument conf.level :

t.test(d$heures.tv, conf.level = 0.9)

    One Sample t-test

data:  d$heures.tv
t = 56.505, df = 1994, p-value < 2.2e-16
alternative hypothesis: true mean is not equal to 0
90 percent confidence interval:
 2.181138 2.311995
sample estimates:
mean of x 
 2.246566 

Le nombre d’heures moyennes à regarder la télévision parmi les enquêtés s’avère être de 2,2 heures, avec un intervalle de confiance à 95 % de [2,17 - 2,33] et un intervalle de confiance à 90 % de [2,18 - 2,31].

Intervalle de confiance d’une proportion

La fonction prop.test permet de calculer l’intervalle de confiance d’une proportion. Une première possibilité consiste à lui transmettre une table à une dimension et deux entrées. Par exemple, si l’on s’intéresse à la proportion de personnes ayant pratiqué une activité physique au cours des douze derniers mois :

freq(d$sport)
prop.test(table(d$sport))

    1-sample proportions test with continuity correction

data:  table(d$sport), null probability 0.5
X-squared = 152.9, df = 1, p-value < 2.2e-16
alternative hypothesis: true p is not equal to 0.5
95 percent confidence interval:
 0.6169447 0.6595179
sample estimates:
     p 
0.6385 

On remarquera que la fonction a calculé l’intervalle de confiance correspondant à la première entrée du tableau, autrement dit celui de la proportion d’enquêtés n’ayant pas pratiqué une activité sportive. Or, nous sommes intéressé par la proportion complémentaire, à savoir celle d’enquêtés ayant pratiqué une activité sportive. On peut dès lors modifier l’ordre de la table en indiquant notre modalité d’intérêt avec la fonction relevel ou bien indiquer à prop.test d’abord le nombre de succès puis l’effectif total :

prop.test(table(relevel(d$sport, "Oui")))

    1-sample proportions test with continuity correction

data:  table(relevel(d$sport, "Oui")), null probability 0.5
X-squared = 152.9, df = 1, p-value < 2.2e-16
alternative hypothesis: true p is not equal to 0.5
95 percent confidence interval:
 0.3404821 0.3830553
sample estimates:
     p 
0.3615 
prop.test(sum(d$sport == "Oui"), length(d$sport))

    1-sample proportions test with continuity correction

data:  sum(d$sport == "Oui") out of length(d$sport), null probability 0.5
X-squared = 152.9, df = 1, p-value < 2.2e-16
alternative hypothesis: true p is not equal to 0.5
95 percent confidence interval:
 0.3404821 0.3830553
sample estimates:
     p 
0.3615 

Enfin, le niveau de confiance peut être modifié via l’argument conf.level :

prop.test(table(relevel(d$sport, "Oui")), conf.level = 0.9)

    1-sample proportions test with continuity correction

data:  table(relevel(d$sport, "Oui")), null probability 0.5
X-squared = 152.9, df = 1, p-value < 2.2e-16
alternative hypothesis: true p is not equal to 0.5
90 percent confidence interval:
 0.3437806 0.3795989
sample estimates:
     p 
0.3615 

Il existe de nombreuses manières de calculer un intervalle de confiance pour une proportion. En l’occurence, l’intervalle calculé par prop.test correspond dans le cas présent à un intervalle bilatéral selon la méthode des scores de Wilson avec correction de continuité. Pour plus d’information, on pourra lire http://joseph.larmarange.net/?Intervalle-de-confiance-bilateral.

Pour se simplifier un peu la vie, le package JLutils propose une fonction prop.ci (et ses deux variantes prop.ci.lower et prop.ci.upper) permettant d’appeler plus facilement prop.test et renvoyant directement l’intervalle de confiance.

JLutils n’étant disponible que sur GitHub, on aura recours au package devtools et à sa fonction install_github pour l’installer :

library(devtools)
install_github("larmarange/JLutils")

prop.ci fonction accepte directement un tri à plat obtenu avec table, un vecteur de données, un vecteur logique (issu d’une condition), ou bien le nombre de succès et le nombre total d’essais. Voir les exemples ci-après :

library(JLutils)
freq(d$sport)
prop.ci(d$sport)
[1] 0.6169447 0.6595179
prop.ci.lower(d$sport)
[1] 0.6169447
prop.ci.upper(d$sport)
[1] 0.6595179
prop.ci(d$sport, conf.level = 0.9)
[1] 0.6204011 0.6562194
prop.ci(table(d$sport))
[1] 0.6169447 0.6595179
prop.ci(d$sport == "Non")
[1] 0.6169447 0.6595179
prop.ci(d$sport == "Oui")
[1] 0.3404821 0.3830553
prop.ci.lower(c(1277, 723), n = 2000)
[1] 0.6169447 0.3404821
prop.ci.upper(c(1277, 723), n = 2000)
[1] 0.6595179 0.3830553

Données pondérées et l’extension survey

Lorsque l’on utilise des données pondérées définies à l’aide de l’extension survey1, l’intervalle de confiance d’une moyenne s’obtient avec confint et celui d’une proportion avec svyciprop.

Quelques exemples :

library(survey)
dw <- svydesign(ids = ~1, data = d, weights = ~poids)
svymean(~age, dw)
      mean     SE
age 46.347 0.5284
confint(svymean(~age, dw)) # Intervalle de confiance d'une moyenne
      2.5 %   97.5 %
age 45.3117 47.38282
confint(svyby(~age, ~sexe, dw, svymean)) # Intervalles de confiance pour chaque sexe
         2.5 %   97.5 %
Homme 43.74781 46.65618
Femme 45.88867 48.79758
freq(svytable(~sexe, dw))
svyciprop(~sexe, dw) # Intervalle de confiance d'une proportion
            2.5% 97.5%
sexe 0.535 0.507  0.56

  1. Voir le chapitre dédié aux données pondérées.

Comparaisons (moyennes et proportions)

Nous utiliserons dans ce chapitre les données de l’enquête Histoire de vie 2003 fournies avec l’extension questionr.

library(questionr)
data("hdv2003")
d <- hdv2003

Comparaison de moyennes

On peut calculer la moyenne d’âge des deux groupes en utilisant la fonction tapply1 :

tapply(d$age, d$hard.rock, mean)
     Non      Oui 
48.30211 27.57143 

L’écart est important. Est-il statistiquement significatif ? Pour cela on peut faire un test t de Student de comparaison de moyennes à l’aide de la fonction t.test :

t.test(age ~ hard.rock, data = d)

    Welch Two Sample t-test

data:  age by hard.rock
t = 9.6404, df = 13.848, p-value = 1.611e-07
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 16.11379 25.34758
sample estimates:
mean in group Non mean in group Oui 
         48.30211          27.57143 

Le test est extrêmement significatif. L’intervalle de confiance à 95 % de la différence entre les deux moyennes va de 16,1 ans à 25,3 ans.

La valeur affichée pour p est de 1.611e-07. Cette valeur peut paraître étrange pour les non avertis. Cela signifie tout simplement 1,611 multiplié par 10 à la puissance -7, autrement dit 0,0000001611. Cette manière de représenter un nombre est couramment appelée notation scientifique.

Pour plus de détails, voir http://fr.wikipedia.org/wiki/Notation_scientifique.

Il est possible de désactiver la notation scientifique avec la commande :

options(scipen = 999)

Pour rétablir la notation scientifique :

options(scipen = 0)

Nous sommes cependant allés un peu vite en besogne, car nous avons négligé une hypothèse fondamentale du test t : les ensembles de valeur comparés doivent suivre approximativement une loi normale et être de même variance2.

Dans le test de Student, on suppose l’égalité des variances parentes, ce qui permet de former une estimation commune de la variance des deux échantillons (on parle de pooled variance), qui revient à une moyenne pondérée des variances estimées à partir des deux échantillons. Dans le cas où l’on souhaite relaxer cette hypothèse, le test de Welch ou la correction de Satterthwaite reposent sur l’idée que l’on utilise les deux estimations de variance séparément, suivie d’une approximation des degrés de liberté pour la somme de ces deux variances. Le même principe s’applique dans le cas de l’analyse de variance à un facteur (cf. oneway.test).

Comment vérifier que l’hypothèse de normalité est acceptable pour ces données ? D’abord avec un petit graphique composés de deux histogrammes :

par(mfrow = c(1, 2))
hist(d$age[d$hard.rock == "Oui"], main = "Hard rock", col = "red")
hist(d$age[d$hard.rock == "Non"], main = "Sans hard rock", col = "red")
Distribution des âges pour appréciation de la normalité

Une alternative consisterait à utiliser des graphiques de type QQ-plot, à l’aide de la fonction qnorm, même si leur utilisation et leur interprétation ne sera pas détaillée ici.

La fonction par permet de modifier de nombreux paramètres graphiques. Ici, l’instruction par(mfrow = c(1, 2)) sert à indiquer que l’on souhaite afficher deux graphiques sur une même fenêtre, plus précisément que la fenêtre doit comporter une ligne et deux colonnes.

Ça a l’air à peu près bon pour les « Sans hard rock », mais un peu plus limite pour les fans de Metallica, dont les effectifs sont d’ailleurs assez faibles. Si on veut en avoir le cœur net on peut utiliser le test de normalité de Shapiro-Wilk avec la fonction shapiro.test :

shapiro.test(d$age[d$hard.rock == "Oui"])

    Shapiro-Wilk normality test

data:  d$age[d$hard.rock == "Oui"]
W = 0.86931, p-value = 0.04104
shapiro.test(d$age[d$hard.rock == "Non"])

    Shapiro-Wilk normality test

data:  d$age[d$hard.rock == "Non"]
W = 0.98141, p-value = 2.079e-15

Visiblement, le test estime que les distributions ne sont pas suffisamment proches de la normalité dans les deux cas.

Et concernant l’égalité des variances ?

tapply(d$age, d$hard.rock, var)
      Non       Oui 
285.62858  62.72527 

L’écart n’a pas l’air négligeable. On peut le vérifier avec le test d’égalité des variances fourni par la fonction var.test :

var.test(age ~ hard.rock, data = d)

    F test to compare two variances

data:  age by hard.rock
F = 4.5536, num df = 1985, denom df = 13, p-value =
0.003217
alternative hypothesis: true ratio of variances is not equal to 1
95 percent confidence interval:
 1.751826 8.694405
sample estimates:
ratio of variances 
          4.553644 

La différence est très significative. En toute rigueur le test t n’aurait donc pas pu être utilisé. Cela dit, il convient de rappeler que ce test statistique (1) suppose la normalité des distributions et (2) considère comme hypothèse nulle l’égalité des variances (parentes) – ce que l’on souhaiterait vérifier alors qu’on ne peut pas accepter l’hypothèse nulle dans un cadre d’inférence fréquentiste – sans que l’on définisse réellement ce que signifie des variances différentes sur le plan pratique. Est-ce qu’une variation de la variance du simple au double est pertinente au regard du domaine d’étude, ou bien faut-il décider qu’à partir d’un rapport de 4 on peut considérer qu’il y a bien une différence importante entre deux variances ? Sans avoir fixé au préalable cette hypothèse alternative, on ne peut guère conclure à partir de ce test. Une alternative consiste à comparer la forme des distributions à l’aide, par exemple, de diagrammes de type boîtes à moustaches.

Damned ! Ces maudits tests statistiques vont-ils nous empêcher de faire connaître au monde entier notre fabuleuse découverte sur l’âge des fans de Sepultura ? Non ! Car voici qu’approche à l’horizon un nouveau test, connu sous le nom de Wilcoxon/Mann-Whitney. Celui-ci a l’avantage d’être non-paramétrique, c’est à dire de ne faire aucune hypothèse sur la distribution des échantillons comparés, à l’exception que celles-ci ont des formes à peu près comparables (essentiellement en termes de variance). Attention, il ne s’agit pas d’un test comparant les différences de médianes (pour cela il existe le test de Mood) mais d’un test reposant sur la somme des rangs des observations, au lieu des valeurs brutes, dans les deux groupes :

wilcox.test(age ~ hard.rock, data = d)

    Wilcoxon rank sum test with continuity correction

data:  age by hard.rock
W = 23980, p-value = 2.856e-06
alternative hypothesis: true location shift is not equal to 0

Ouf ! La différence est hautement significative3. Nous allons donc pouvoir entamer la rédaction de notre article pour la Revue française de sociologie.

Comparaison de proportions

La fonction prop.test, que nous avons déjà rencontrée pour calculer l’intervalle de confiance d’une proportion (voir le chapitre dédié aux intervalles de confiance) permets également d’effectuer un test de comparaison de deux proportions.

Supposons que l’on souhaite comparer la proportion de personnes faisant du sport entre ceux qui lisent des bandes dessinées et les autres :

tab <- xtabs(~ lecture.bd + sport, data = d)
lprop(tab)
          sport
lecture.bd Non   Oui   Total
  Non       64.2  35.8 100.0
  Oui       48.9  51.1 100.0
  Ensemble  63.8  36.1 100.0

Une représentation graphique sous forme de diagramme en barres peut être définie comme suit :

barplot(prop.table(tab, margin = 1) * 100, beside = TRUE, ylim = c(0, 100), xlab = "Sport", legend.text = c("Lecture : non", "Lecture : oui"))
Répartition des individus (en %) selon les variables sport et lecture

Il suffit de transmettre notre tableau croisé (à 2×2 dimensions) à prop.test :

prop.test(tab)

    2-sample test for equality of proportions with
    continuity correction

data:  tab
X-squared = 4, df = 1, p-value = 0.0455
alternative hypothesis: two.sided
95 percent confidence interval:
 -0.002652453  0.308107236
sample estimates:
   prop 1    prop 2 
0.6420891 0.4893617 

On pourra également avoir recours à la fonction fisher.test qui renverra notamment l’odds ratio et son intervalle de confiance correspondant :

fisher.test(tab)

    Fisher's Exact Test for Count Data

data:  tab
p-value = 0.0445
alternative hypothesis: true odds ratio is not equal to 1
95 percent confidence interval:
 1.003372 3.497759
sample estimates:
odds ratio 
  1.871433 

Formellement, le test de Fisher suppose que les marges du tableau (totaux lignes et colonnes) sont fixées, puisqu’il repose sur une loi hypergéométrique, et donc celui-ci se prête plus au cas des situations expérimentales (plans d’expérience, essais cliniques) qu’au cas des données tirées d’études observationnelles.

On pourra aussi avoir recours à la fonction odds.ratio de l’extension questionr qui réalise le même calcul mais présente le résultat légèrement différemment :

odds.ratio(tab)

Note : pour le calcul du risque relatif, on pourra regarder du côté de la fonction relrisk de l’extension mosaic.

² et dérivés

Dans le cadre d’un tableau croisé, on peut tester l’existence d’un lien entre les modalités de deux variables, avec le très classique test du ² de Pearson4. Celui-ci s’obtient grâce à la fonction chisq.test, appliquée au tableau croisé obtenu avec table ou xtabs5 :

d$qualreg <- as.character(d$qualif)
d$qualreg[d$qualif %in% c("Ouvrier specialise", "Ouvrier qualifie")] <- "Ouvrier"
d$qualreg[d$qualif %in% c(
  "Profession intermediaire",
  "Technicien"
)] <- "Intermediaire"

tab <- table(d$sport, d$qualreg)
tab
     
      Autre Cadre Employe Intermediaire Ouvrier
  Non    38   117     401           127     381
  Oui    20   143     193           119     114
chisq.test(tab)

    Pearson's Chi-squared test

data:  tab
X-squared = 96.798, df = 4, p-value < 2.2e-16

Le test est hautement significatif : on ne peut donc pas considérer qu’il y a indépendance entre les lignes et les colonnes du tableau.

Notons que l’agrégation des niveaux d’une variable catégorielle peut être réalisée d’une manière différente en utilisant les fonctions de gestion des niveaux d’un facteur. Les expressions précédentes sont donc équivalentes à l’approche ci-après, qui ne nécessite pas de convertir d$qualif en chaîne de caractères :

d$qualreg <- d$qualif
levels(d$qualreg)[1:2] <- "Ouvrier"
levels(d$qualreg)[2:3] <- "Intermédiaire"
tab <- table(d$sport, d$qualreg)

On peut affiner l’interprétation du test en déterminant dans quelle cas l’écart à l’indépendance est le plus significatif en utilisant les résidus du test. Ceux-ci sont notamment affichables avec la fonction chisq.residuals de questionr :

chisq.residuals(tab)
     
      Autre Cadre Employe Intermediaire Ouvrier
  Non  0.11 -3.89    0.95         -2.49    3.49
  Oui -0.15  5.23   -1.28          3.35   -4.70

Les cases pour lesquelles l’écart à l’indépendance est significatif ont un résidu dont la valeur est supérieure à 2 ou inférieure à -2 (le fameux nombre 2 issu de la loi normale, au-delà duquel on s’attend à observer au maximum 2,5 % des observations). Ici on constate que la pratique d’un sport est sur-représentée parmi les cadres et, à un niveau un peu moindre, parmi les professions intermédiaires, tandis qu’elle est sous-représentée chez les ouvriers.

Enfin, on peut calculer le coefficient de contingence de Cramer du tableau, qui présente l’avantage de pouvoir être comparé par la suite à celui calculé sur d’autres tableaux croisés. On peut pour cela utiliser la fonction cramer.v de questionr :

cramer.v(tab)
[1] 0.24199

Pour un tableau à 2×2 entrées, comme discuté plus haut, il est également possible de calculer le test exact de Fisher avec la fonction fisher.test. On peut soit lui passer le résultat de table ou xtabs, soit directement les deux variables à croiser.

lprop(table(d$sexe, d$cuisine))
          
           Non   Oui   Total
  Homme     70.0  30.0 100.0
  Femme     44.5  55.5 100.0
  Ensemble  56.0  44.0 100.0
fisher.test(table(d$sexe, d$cuisine))

    Fisher's Exact Test for Count Data

data:  table(d$sexe, d$cuisine)
p-value < 2.2e-16
alternative hypothesis: true odds ratio is not equal to 1
95 percent confidence interval:
 2.402598 3.513723
sample estimates:
odds ratio 
  2.903253 

Le test du ² de Pearson étant assez robuste quant aux déviations par rapport aux hypothèses d’applications du test (effectifs théoriques tous = 5), le test de Fisher présente en général peu d’intérêt dans le cas de l’analyse des tableaux de contingence.

Données pondérées et l’extension survey

Lorsque l’on utilise des données pondérées, on aura recours à l’extension survey6.

Préparons des données d’exemple :

library(survey)
dw <- svydesign(ids = ~1, data = d, weights = ~poids)

Pour comparer deux moyennes à l’aide d’un test t on aura recours à svyttest :

svyttest(age ~ sexe, dw)

    Design-based t-test

data:  age ~ sexe
t = 2.0404, df = 1998, p-value = 0.04144
alternative hypothesis: true difference in mean is not equal to 0
95 percent confidence interval:
 0.08440815 4.19785019
sample estimates:
difference in mean 
          2.141129 

Pour le test de Wilcoxon/Mann-Whitney, on pourra avoir recours à svyranktest :

svyranktest(age ~ hard.rock, dw)

    Design-based KruskalWallis test

data:  age ~ hard.rock
t = -11.12, df = 1998, p-value < 2.2e-16
alternative hypothesis: true difference in mean rank score is not equal to 0
sample estimates:
difference in mean rank score 
                   -0.3636859 

On ne peut pas utiliser chisq.test directement sur un tableau généré par svytable. Les effectifs étant extrapolés à partir de la pondération, les résultats du test seraient complètement faussés. Si on veut faire un test du ² sur un tableau croisé pondéré, il faut utiliser svychisq :

rprop(svytable(~ sexe + clso, dw))
          clso
sexe       Oui   Non   Ne sait pas Total
  Homme     51.6  47.0   1.4       100.0
  Femme     43.9  54.8   1.3       100.0
  Ensemble  47.5  51.1   1.4       100.0
svychisq(~ sexe + clso, dw)

    Pearson's X^2: Rao & Scott adjustment

data:  svychisq(~sexe + clso, dw)
F = 3.3331, ndf = 1.9734, ddf = 3944.9024, p-value =
0.03641

L’extension survey ne propose pas de version adaptée du test exact de Fisher. Pour comparer deux proportions, on aura donc recours au test du ² :

rprop(svytable(~ lecture.bd + sport, dw))
          sport
lecture.bd Non   Oui   Total
  Non       61.0  39.0 100.0
  Oui       46.8  53.2 100.0
  Ensemble  60.7  39.3 100.0
svychisq(~ lecture.bd + sport, dw)

    Pearson's X^2: Rao & Scott adjustment

data:  svychisq(~lecture.bd + sport, dw)
F = 2.6213, ndf = 1, ddf = 1999, p-value = 0.1056

Tests dans les tableaux de gtsummary

Lorsque l’on réalise un tableau croisé avec tbl_summary ou tbl_svysummary de l’extension gtsummary, il est possible d’ajouter des tests de comparaison avec add_p.

library(gtsummary)
theme_gtsummary_language("fr", decimal.mark = ",", big.mark = " ")
Setting `language: fr` theme
d %>%
  tbl_summary(
    include = c("hard.rock", "age", "sport"),
    by = "hard.rock"
  ) %>%
  add_p()
Caractéristique Non, N = 1 9861 Oui, N = 141 p-value2
age 48 (35 – 60) 26 (22 – 30) <0,001
sport >0,9
Non 1 268 (64%) 9 (64%)
Oui 718 (36%) 5 (36%)

1 Statistique présentée: Médiane (EI); n (%)

2 Test statistique réalisé: test de Wilcoxon-Mann-Whitney; test du khi-deux d'indépendance

Il est possible de préciser le type de test à utiliser.

d %>%
  tbl_summary(
    include = c("hard.rock", "age"),
    by = "hard.rock"
  ) %>%
  add_p(test = list(all_continuous() ~ "wilcox.test"))
Caractéristique Non, N = 1 9861 Oui, N = 141 p-value2
age 48 (35 – 60) 26 (22 – 30) <0,001

1 Statistique présentée: Médiane (EI)

2 Test statistique réalisé: test de Wilcoxon-Mann-Whitney

Cela fonctionne également avec les données pondérées et les plans d’échantillonnage complexe.

dw %>%
  tbl_svysummary(
    include = c("hard.rock", "age", "sport"),
    by = "hard.rock"
  ) %>%
  add_p()
Caractéristique Non, N = 10 981 9631 Oui, N = 89 2641 p-value2
age 45 (31 – 60) 23 (19 – 28) <0,001
sport 0,8
Non 6 656 841 (61%) 57 920 (65%)
Oui 4 325 122 (39%) 31 344 (35%)

1 Statistique présentée: Médiane (EI); n (%)

2 Test statistique réalisé: Wilcoxon rank-sum test for complex survey samples; chi-squared test with Rao & Scott's second-order correction


  1. La fonction tapply est présentée plus en détails dans le chapitre Manipulation de données.

  2. Concernant cette seconde condition, t.test utilise par défaut un test de Welch qui ne suppose pas l’égalité des variances parentes ; il est toutefois possible d’utiliser le test classique de Student en spécifiant l’option var.equal = TRUE.

  3. Ce test peut également fournir un intervalle de confiance avec l’option conf.int=TRUE.

  4. On ne donnera pas plus d’indications sur le test du ² ici. Les personnes désirant une présentation plus détaillée pourront se reporter (attention, séance d’autopromotion !) à la page suivante : http://alea.fr.eu.org/pages/khi2.

  5. On peut aussi appliquer directement le test en spécifiant les deux variables à croiser via chisq.test(d$qualreg, d$sport).

  6. Voir le chapitre dédié aux données pondérées.

Définir un plan d’échantillonnage complexe

L’extension survey ne permet pas seulement d’indiquer une variable de pondération mais également de prendre les spécificités du plan d’échantillonnage (strates, grappes, …). Le plan d’échantillonnage ne joue pas seulement sur la pondération des données, mais influence le calcul des variances et par ricochet tous les tests statistiques. Deux échantillons identiques avec la même variable de pondération mais des designs différents produiront les mêmes moyennes et proportions mais des intervalles de confiance différents.

Le site officiel (en anglais) comporte beaucoup d’informations, mais pas forcément très accessibles :
http://r-survey.r-forge.r-project.org/.

Différents types d’échantillonnage

L’échantillonnage aléatoire simple ou échantillonnage équiprobable est une méthode pour laquelle tous les échantillons possibles (de même taille) ont la même probabilité d’être choisis et tous les éléments de la population ont une chance égale de faire partie de l’échantillon. C’est l’échantillonnage le plus simple : chaque individu à la même probabilité d’être sélectionné.

L’échantillonnage stratifié est une méthode qui consiste d’abord à subdiviser la population en groupes homogènes (strates) pour ensuite extraire un échantillon aléatoire de chaque strate. Cette méthode suppose la connaissance de la structure de la population. Pour estimer les paramètres, les résultats doivent être pondérés par l’importance relative de chaque strate dans la population.

L’échantillonnage par grappes est une méthode qui consiste à choisir un échantillon aléatoire d’unités qui sont elles-mêmes des sous-ensembles de la population (grappes ou clusters en anglais). Cette méthode suppose que les unités de chaque grappe sont représentatives. Elle possède l’avantage d’être souvent plus économique.

Il est possible de combiner plusieurs de ces approches. Par exemple, les Enquêtes Démographiques et de Santé1 (EDS) sont des enquêtes stratifiées en grappes à deux degrés. Dans un premier temps, la population est divisée en strates par région et milieu de résidence. Dans chaque strate, des zones d’enquêtes, correspondant à des unités de recensement, sont tirées au sort avec une probabilité proportionnelle au nombre de ménages de chaque zone au dernier recensement de population. Enfin, au sein de chaque zone d’enquête sélectionnée, un recensement de l’ensemble des ménages est effectué puis un nombre identique de ménages par zone d’enquête est tiré au sort de manière alétoire simple.

Les options de svydesign

La fonction svydesign accepte plusieurs arguments décrits sur sa page d’aide (obtenue avec la commande ?svydesign).

L’agument data permet de spécifier le tableau de données contenant les observations.

L’argument ids est obligatoire et spécifie sous la forme d’une formule les identifiants des différents niveaux d’un tirage en grappe. S’il s’agit d’un échantillon aléatoire simple, on entrera ids=˜1. Autre situation : supposons une étude portant sur la population française. Dans un premier temps, on a tiré au sort un certain nombre de départements français. Dans un second temps, on tire au sort dans chaque département des communes. Dans chaque commune sélectionnée, on tire au sort des quartiers. Enfin, on interroge de manière exhaustive toutes les personnes habitant les quartiers enquêtés. Notre fichier de données devra donc comporter pour chaque observation les variables id_departement, id_commune et id_quartier. On écrira alors pour l’argument ids la valeur suivante :
ids=˜id_departement+id_commune+id_quartier.

Si l’échantillon est stratifié, on spécifiera les strates à l’aide de l’argument strata en spécifiant la variable contenant l’identifiant des strates. Par exemple : strata=˜id_strate.

Il faut encore spécifier les probabilités de tirage de chaque cluster ou bien la pondération des individus. Si l’on dispose de la probabilité de chaque observation d’être sélectionnée, on utilisera l’argument probs. Si, par contre, on connaît la pondération de chaque observation (qui doit être proportionnelle à l’inverse de cette probabilité), on utilisera l’argument weights.

Si l’échantillon est stratifié, qu’au sein de chaque strate les individus ont été tirés au sort de manière aléatoire et que l’on connaît la taille de chaque strate, il est possible de ne pas avoir à spécifier la probabilité de tirage ou la pondération de chaque observation. Il est préférable de fournir une variable contenant la taille de chaque strate à l’argument fpc. De plus, dans ce cas-là, une petite correction sera appliquée au modèle pour prendre en compte la taille finie de chaque strate.

Quelques exemples

# Échantillonnage aléatoire simple
plan <- svydesign(ids = ~1, data = donnees)

# Échantillonnage stratifié à un seul niveau (la taille de chaque strate est connue)
plan <- svydesign(ids = ~1, data = donnees, fpc = ~taille)

# Échantillonnage en grappes avec tirages à quatre degrés (departement, commune, quartier, individus). La probabilité de tirage de chaque niveau de cluster est connue.
plan <- svydesign(ids = ~ id_departement + id_commune + id_quartier, data = donnees, probs = ~ proba_departement + proba_commune + proba_quartier)

# Échantillonnage stratifié avec tirage à deux degrés (clusters et individus). Le poids statistiques de chaque observation est connu.
plan <- svydesign(ids = ~id_cluster, data = donnees, strata = ~id_strate, weights = ~poids)

Prenons l’exemple d’une Enquête Démographique et de Santé. Le nom des différentes variables est standardisé et commun quelle que soit l’enquête. Nous supposerons que vous avez importé le fichier individus dans un tableau de données nommés eds. Le poids statistique de chaque individu est fourni par la variable V005 qui doit au préalable être divisée par un million. Les grappes d’échantillonnage au premier degré sont fournies par la variable V021 (primary sample unit). Si elle n’est pas renseignée, on pourra utilisier le numéro de grappe V001. Enfin, le milieu de résidence (urbain / rural) est fourni par V025 et la région par V024. Pour rappel, l’échantillon a été stratifié à la fois par région et par mileu de résidence. Certaines enquêtes fournissent directement un numéro de strate via V022. Si tel est le cas, on pourra préciser le plan d’échantillonnage ainsi :

eds$poids <- eds$V005 / 1000000
design.eds <- svydesign(ids = ~V021, data = eds, strata = ~V022, weights = ~poids)

Si V022 n’est pas fourni mais que l’enquête a bien été stratifiée par région et milieu de résidence (vérifiez toujours le premier chapitre du rapport d’enquête), on pourra créer une variable strate ainsi2 :

eds$strate <- as.factor(as.integer(eds$V024) * 10 + as.integer(eds$V025))
levels(eds$strate) <- c(paste(levels(eds$V024), "Urbain"), paste(levels(eds$V024), "Rural"))
design.eds <- svydesign(ids = ~V021, data = eds, strata = ~strate, weights = ~poids)

Il n’est pas aisé de modifier des variables dans un objet survey.design. Il est donc préférable de procéder à l’ensemble des nettoyages, recodages de variables (et au besoin transformation des vecteurs labellisés en facteur), avant de convertir le tableau de données en objet survey et de procéder aux analyses.

Une autre possibilité et d’utiliser l’extension srvyr qui permet d’utiliser les verbes de dplyr avec survey. Le fonctionnement de cette extension est expliqué dans une vignette dédiée : https://cran.r-project.org/web/packages/srvyr/vignettes/srvyr-vs-survey.html.

Extraire un sous-échantillon

Si l’on souhaite travailler sur un sous-échantillon tout en gardant les informations d’échantillonnage, on utilisera la fonction subset présentée en détail dans le chapitre Manipulation de données.

sous <- subset(plan, sexe == "Femme" & age >= 40)

  1. Vaste programme d’enquêtes réalisées à intervalles réguliers dans les pays du Sud, disponibles sur http://www.dhsprogram.com/.

  2. L’astuce consiste à utiliser as.integer pour obtenir le code des facteurs et non leur valeur textuelle. L’addition des deux valeurs après multiplication du code de la région par 10 permet d’obtenir une valeur unique pour chaque combinaison des deux variables. On retransforme le résultat en facteurs puis on modifie les étiquettes des modalités.

Régression linéaire

Ce chapitre est en cours d’écriture.

On pourra se référer au chapitre 6 Régressions linéaires avec R du support de cours d’Ewen Gallic intitulé Logiciel R et programmation (http://egallic.fr/Enseignement/R/m1_stat_eco_logiciel_R.pdf).

Régression logistique binaire, multinomiale et ordinale

La version originale de ce chapitre a été écrite par Joseph Larmarange dans le cadre du support de cours Introduction à l’analyse d’enquêtes avec R.

La régression logistique est fréquemment utilisée en sciences sociales car elle permet d’effectuer un raisonnement dit toutes choses étant égales par ailleurs. Plus précisément, la régression logistique a pour but d’isoler les effets de chaque variable, c’est-à-dire d’identifier les effets résiduels d’une variable explicative sur une variable d’intérêt, une fois pris en compte les autres variables explicatives introduites dans le modèle. La régression logistique est ainsi prisée en épidémiologie pour identifier les facteurs associés à telle ou telle pathologie.

La régression logistique ordinaire ou régression logistique binaire vise à expliquer une variable d’intérêt binaire (c’est-à-dire de type « oui / non » ou « vrai / faux »). Les variables explicatives qui seront introduites dans le modèle peuvent être quantitatives ou qualitatives.

La régression logistique multinomiale est une extension de la régression logistique aux variables qualitatives à trois modalités ou plus, la régression logistique ordinale aux variables qualitatives à trois modalités ou plus qui sont ordonnées hiérarchiquement.

Préparation des données

Dans ce chapite, nous allons encore une fois utiliser les données de l’enquête Histoire de vie, fournies avec l’extension questionr.

library(questionr)
data(hdv2003)
d <- hdv2003

À titre d’exemple, nous allons étudier l’effet de l’âge, du sexe, du niveau d’étude, de la pratique religieuse et du nombre moyen d’heures passées à regarder la télévision par jour sur le fait de pratiquer un sport.

En premier lieu, il importe de vérifier que notre variable d’intérêt (ici sport) est correctement codée. Une possibilité consiste à créer une variable booléenne (vrai / faux) selon que l’individu a pratiqué du sport ou non :

d$sport2 <- FALSE
d$sport2[d$sport == "Oui"] <- TRUE

Dans le cas présent, cette variable n’a pas de valeur manquante. Mais, le cas échéant, il importe de bien coder les valeurs manquantes en NA, les individus en question étant alors exclu de l’analyse.

Il n’est pas forcément nécessaire de transformer notre variable d’intérêt en variable booléenne. En effet, R accepte sans problème une variable de type facteur. Cependant, l’ordre des valeurs d’un facteur a de l’importance. En effet, R considère toujours la première modalité comme étant la modalité de référence. Dans le cas de la variable d’intérêt, la modalité de référence correspond au fait de ne pas remplir le critère étudié, dans notre exemple au fait de ne pas avoir eu d’activité sportive au cours des douze derniers mois.

Pour connaître l’ordre des modalités d’une variable de type facteur, on peut utiliser la fonction levels ou bien encore tout simplement la fonction freq de l’extension questionr :

levels(d$sport)
[1] "Non" "Oui"
freq(d$sport)

Dans notre exemple, la modalité « Non » est déjà la première modalité. Il n’y a donc pas besoin de modifier notre variable. Si ce n’est pas le cas, il faudra modifier la modalité de référence avec la fonction relevel comme nous allons le voir un peu plus loin.

Il est possible d’indiquer un facteur à plus de deux modalités. Dans une telle situation, R considérera que tous les modalités, sauf la modalité de référence, est une réalisation de la variable d’intérêt. Cela serait correct, par exemple, si notre variable sport était codée ainsi : « Non », « Oui, toutes les semaines », « Oui, au moins une fois par mois », « Oui, moins d’une fois par mois ». Cependant, afin d’éviter tout risque d’erreur ou de mauvaise interprétation, il est vivement conseillé de recoder au préalable sa variable d’intérêt en un facteur à deux modalités.

La notion de modalité de référence s’applique également aux variables explicatives qualitatives. En effet, dans un modèle, tous les coefficients sont calculés par rapport à la modalité de référence. Il importe de choisir une modalité de référence qui fasse sens afin de faciliter l’interprétation. Par ailleurs, ce choix peut également dépendre de la manière dont on souhaite présenter les résultats. De manière générale on évitera de choisir comme référence une modalité peu représentée dans l’échantillon ou bien une modalité correspondant à une situation atypique.

Prenons l’exemple de la variable sexe. Souhaite-t-on connaitre l’effet d’être une femme par rapport au fait d’être un homme ou bien l’effet d’être un homme par rapport au fait d’être une femme ? Si l’on opte pour le second, alors notre modalité de référence sera le sexe féminin. Comme est codée cette variable ?

freq(d$sexe)

La modalité « Femme » s’avère ne pas être la première modalité. Nous devons appliquer la fonction relevel :

d$sexe <- relevel(d$sexe, "Femme")
freq(d$sexe)

Données labellisées

Si l’on utilise des données labellisées (voir le chapitre dédié), nos variables catégorielles seront stockées sous la forme d’un vecteur numérique avec des étiquettes. Il sera donc nécessaire de convertir ces variables en facteurs, tout simplement avec la fonction to_factor de l’extension labelled qui pourra utiliser les étiquettes de valeurs comme modalités du facteur.

Les variables age et heures.tv sont des variables quantitatives. Il importe de vérifier qu’elles sont bien enregistrées en tant que variables numériques. En effet, il arrive parfois que dans le fichier source les variables quantitatives soient renseignées sous forme de valeur textuelle et non sous forme numérique.

str(d$age)
 int [1:2000] 28 23 59 34 71 35 60 47 20 28 ...
str(d$heures.tv)
 num [1:2000] 0 1 0 2 3 2 2.9 1 2 2 ...

Nos deux variables sont bien renseignées sous forme numérique.

Cependant, l’effet de l’âge est rarement linéaire. Un exemple trivial est par exemple le fait d’occuper un emploi qui sera moins fréquent aux jeunes âges et aux âges élevés. Dès lors, on pourra transformer la variable age en groupe d’âges avec la fonction cut (voir le chapitre Manipulation de données) :

d$grpage <- cut(d$age, c(16, 25, 45, 65, 99), right = FALSE, include.lowest = TRUE)
freq(d$grpage)

Jetons maintenant un oeil à la variable nivetud :

freq(d$nivetud)

En premier lieu, cette variable est détaillée en pas moins de huit modalités dont certaines sont peu représentées (seulement 39 individus soit 2 % n’ont jamais fait d’études par exemple). Afin d’améliorier notre modèle logistique, il peut être pertinent de regrouper certaines modalités (voir le chapitre Manipulation de données) :

d$etud <- d$nivetud
levels(d$etud) <- c(
  "Primaire", "Primaire", "Primaire",
  "Secondaire", "Secondaire", "Technique/Professionnel",
  "Technique/Professionnel", "Supérieur"
)
freq(d$etud)

Notre variable comporte également 112 individus avec une valeur manquante. Si nous conservons cette valeur manquante, ces 112 individus seront, par défaut, exclus de l’analyse. Ces valeurs manquantes n’étant pas négligeable (5,6 %), nous pouvons également faire le choix de considérer ces valeurs manquantes comme une modalité supplémentaire. Auquel cas, nous utiliserons la fonction addNAstr fournie par questionr1 :

levels(d$etud)
[1] "Primaire"                "Secondaire"             
[3] "Technique/Professionnel" "Supérieur"              
d$etud <- addNAstr(d$etud, "manquant")
levels(d$etud)
[1] "Primaire"                "Secondaire"             
[3] "Technique/Professionnel" "Supérieur"              
[5] "manquant"               

Régression logistique binaire

La fonction glm (pour generalized linear models soit modèle linéaire généralisé en français) permet de calculer une grande variété de modèles statistiques. La régression logistique ordinaire correspond au modèle logit de la famille des modèles binomiaux, ce que l’on indique à glm avec l’argument family=binomial(logit).

Le modèle proprement dit sera renseigné sous la forme d’une formule (que nous avons déjà rencontrée dans le chapitre sur la statistique bivariée et présentée plus en détails dans un chapitre dédié). On indiquera d’abord la variable d’intérêt, suivie du signe ~ (que l’on obtient en appuyant sur les touches Alt Gr et 3 sur un clavier de type PC) puis de la liste des variables explicatives séparées par un signe +. Enfin, l’argument data permettra d’indiquer notre tableau de données.

reg <- glm(sport ~ sexe + grpage + etud + relig + heures.tv, data = d, family = binomial(logit))
reg

Call:  glm(formula = sport ~ sexe + grpage + etud + relig + heures.tv, 
    family = binomial(logit), data = d)

Coefficients:
                     (Intercept)  
                       -0.798368  
                       sexeHomme  
                        0.439694  
                   grpage[25,45)  
                       -0.420448  
                   grpage[45,65)  
                       -1.085434  
                   grpage[65,99]  
                       -1.381353  
                  etudSecondaire  
                        0.950571  
     etudTechnique/Professionnel  
                        1.049253  
                   etudSupérieur  
                        1.891667  
                    etudmanquant  
                        2.150428  
     religPratiquant occasionnel  
                       -0.021904  
 religAppartenance sans pratique  
                       -0.006696  
religNi croyance ni appartenance  
                       -0.215389  
                      religRejet  
                       -0.383543  
                religNSP ou NVPR  
                       -0.083789  
                       heures.tv  
                       -0.120911  

Degrees of Freedom: 1994 Total (i.e. Null);  1980 Residual
  (5 observations deleted due to missingness)
Null Deviance:      2609 
Residual Deviance: 2206     AIC: 2236

Il est possible de spécifier des modèles plus complexes. Par exemple, x:y permet d’indiquer l’interaction entre les variables x et y. x * y sera équivalent à x + y + x:y. Pour aller plus loin, voir http://ww2.coastal.edu/kingw/statistics/R-tutorials/formulae.html.

Une présentation plus complète des résultats est obtenue avec la méthode summary :

summary(reg)

Call:
glm(formula = sport ~ sexe + grpage + etud + relig + heures.tv, 
    family = binomial(logit), data = d)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-1.8784  -0.8865  -0.4808   1.0033   2.4222  

Coefficients:
                                  Estimate Std. Error
(Intercept)                      -0.798368   0.323903
sexeHomme                         0.439694   0.106062
grpage[25,45)                    -0.420448   0.228053
grpage[45,65)                    -1.085434   0.237716
grpage[65,99]                    -1.381353   0.273796
etudSecondaire                    0.950571   0.197442
etudTechnique/Professionnel       1.049253   0.189804
etudSupérieur                     1.891667   0.195218
etudmanquant                      2.150428   0.330229
religPratiquant occasionnel      -0.021904   0.189199
religAppartenance sans pratique  -0.006696   0.174737
religNi croyance ni appartenance -0.215389   0.193080
religRejet                       -0.383543   0.285905
religNSP ou NVPR                 -0.083789   0.411028
heures.tv                        -0.120911   0.033591
                                 z value Pr(>|z|)    
(Intercept)                       -2.465 0.013708 *  
sexeHomme                          4.146 3.39e-05 ***
grpage[25,45)                     -1.844 0.065236 .  
grpage[45,65)                     -4.566 4.97e-06 ***
grpage[65,99]                     -5.045 4.53e-07 ***
etudSecondaire                     4.814 1.48e-06 ***
etudTechnique/Professionnel        5.528 3.24e-08 ***
etudSupérieur                      9.690  < 2e-16 ***
etudmanquant                       6.512 7.42e-11 ***
religPratiquant occasionnel       -0.116 0.907833    
religAppartenance sans pratique   -0.038 0.969434    
religNi croyance ni appartenance  -1.116 0.264617    
religRejet                        -1.342 0.179756    
religNSP ou NVPR                  -0.204 0.838470    
heures.tv                         -3.599 0.000319 ***
---
Signif. codes:  
0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 2609.2  on 1994  degrees of freedom
Residual deviance: 2206.2  on 1980  degrees of freedom
  (5 observations deleted due to missingness)
AIC: 2236.2

Number of Fisher Scoring iterations: 4

Coefficients du modèle

Dans le cadre d’un modèle logistique, généralement on ne présente pas les coefficients du modèle mais leur valeur exponentielle, cette dernière correspondant en effet à des odds ratio, également appelés rapports des cotes. L’odds ratio diffère du risque relatif. Cependent son interprétation est similaire. Un odds ratio de 1 signifie l’absence d’effet. Un odds ratio largement supérieur à 1 correspond à une augmentation du phénomène étudié et un odds ratio largement inféieur à 1 correspond à une diminution du phénomène étudié2.

La fonction coef permet d’obtenir les coefficients d’un modèle, confint leurs intervalles de confiance et exp de calculer l’exponentiel. Les odds ratio et leurs intervalles de confiance s’obtiennent ainsi :

exp(coef(reg))
                     (Intercept) 
                       0.4500628 
                       sexeHomme 
                       1.5522329 
                   grpage[25,45) 
                       0.6567525 
                   grpage[45,65) 
                       0.3377552 
                   grpage[65,99] 
                       0.2512383 
                  etudSecondaire 
                       2.5871865 
     etudTechnique/Professionnel 
                       2.8555168 
                   etudSupérieur 
                       6.6304155 
                    etudmanquant 
                       8.5885303 
     religPratiquant occasionnel 
                       0.9783342 
 religAppartenance sans pratique 
                       0.9933267 
religNi croyance ni appartenance 
                       0.8062276 
                      religRejet 
                       0.6814428 
                religNSP ou NVPR 
                       0.9196256 
                       heures.tv 
                       0.8861129 
exp(confint(reg))
Waiting for profiling to be done...
                                     2.5 %     97.5 %
(Intercept)                      0.2377004  0.8473181
sexeHomme                        1.2614265  1.9120047
grpage[25,45)                    0.4194391  1.0274553
grpage[45,65)                    0.2115307  0.5380894
grpage[65,99]                    0.1463860  0.4288023
etudSecondaire                   1.7652682  3.8327896
etudTechnique/Professionnel      1.9804881  4.1729378
etudSupérieur                    4.5517938  9.7950691
etudmanquant                     4.5347799 16.5885323
religPratiquant occasionnel      0.6758807  1.4198530
religAppartenance sans pratique  0.7063000  1.4020242
religNi croyance ni appartenance 0.5524228  1.1782475
religRejet                       0.3868800  1.1889781
religNSP ou NVPR                 0.3996746  2.0215562
heures.tv                        0.8290223  0.9457756

On pourra faciliter la lecture en combinant les deux :

exp(cbind(coef(reg), confint(reg)))
Waiting for profiling to be done...
                                               2.5 %
(Intercept)                      0.4500628 0.2377004
sexeHomme                        1.5522329 1.2614265
grpage[25,45)                    0.6567525 0.4194391
grpage[45,65)                    0.3377552 0.2115307
grpage[65,99]                    0.2512383 0.1463860
etudSecondaire                   2.5871865 1.7652682
etudTechnique/Professionnel      2.8555168 1.9804881
etudSupérieur                    6.6304155 4.5517938
etudmanquant                     8.5885303 4.5347799
religPratiquant occasionnel      0.9783342 0.6758807
religAppartenance sans pratique  0.9933267 0.7063000
religNi croyance ni appartenance 0.8062276 0.5524228
religRejet                       0.6814428 0.3868800
religNSP ou NVPR                 0.9196256 0.3996746
heures.tv                        0.8861129 0.8290223
                                     97.5 %
(Intercept)                       0.8473181
sexeHomme                         1.9120047
grpage[25,45)                     1.0274553
grpage[45,65)                     0.5380894
grpage[65,99]                     0.4288023
etudSecondaire                    3.8327896
etudTechnique/Professionnel       4.1729378
etudSupérieur                     9.7950691
etudmanquant                     16.5885323
religPratiquant occasionnel       1.4198530
religAppartenance sans pratique   1.4020242
religNi croyance ni appartenance  1.1782475
religRejet                        1.1889781
religNSP ou NVPR                  2.0215562
heures.tv                         0.9457756

Pour savoir si un odds ratio diffère significativement de 1 (ce qui est identique au fait que le coefficient soit différent de 0), on pourra se référer à la colonne Pr(>|z|) obtenue avec summary.

Si vous disposez de l’extension questionr, la fonction odds.ratio permet de calculer directement les odds ratio, leur intervalles de confiance et les p-value :

library(questionr)
odds.ratio(reg)
Waiting for profiling to be done...

La fonction tidy de l’extension broom pour récupérer les coefficients du modèle sous la forme d’un tableau de données. On précisera conf.int = TRUE pour obtenir les intervalles de confiance et exponentiate = TRUE pour avoir les odds ratio plutôt que les coefficients bruts.

library(broom)
tidy(reg, conf.int = TRUE, exponentiate = TRUE)

L’extension broom.helpers fournit une fonction tidi_plus_plus qui permet d’améliorer le tableau renvoyé par tidy en y identifiant les variables utilisés, ajoutant les modalités de référence et en proposant des étiquettes plus explicites.

library(broom.helpers)
tidy_plus_plus(reg, exponentiate = TRUE)

Si l’on souhaite avoir des noms de variables plus explicites, il faut ajouter des étiquettes des variables avec var_label de l’extension labelled (voir le chapitre sur les vecteurs labellisés).

Par contre, cette étape doit avoir eu lieu avant le calcul de la régression linéaire.

library(labelled)
var_label(d$sport) <- "Pratique du sport ?"
var_label(d$sexe) <- "Sexe"
var_label(d$grpage) <- "Groupe d'âges"
var_label(d$etud) <- "Niveau d'étude"
var_label(d$relig) <- "Pratique religieuse"
var_label(d$heures.tv) <- "Nombre d'heures passées devant la télévision par jour"
reg <- glm(sport ~ sexe + grpage + etud + relig + heures.tv, data = d, family = binomial(logit))
tidy_plus_plus(reg, exponentiate = TRUE)

La fonction tbl_regression de l’extension gtsummary, qui a recours en interne à broom.helpers, permet d’obtenir un tableau plus propre. Comme nous souhaitons afficher les odds ratios plutôt que les coefficients du modèle, on indiquera exponentiate = TRUE.

library(gtsummary)
tbl_regression(reg, exponentiate = TRUE)
Characteristic OR1 95% CI1 p-value
Sexe
Femme
Homme 1.55 1.26, 1.91 <0.001
Groupe d'âges
[16,25)
[25,45) 0.66 0.42, 1.03 0.065
[45,65) 0.34 0.21, 0.54 <0.001
[65,99] 0.25 0.15, 0.43 <0.001
Niveau d'étude
Primaire
Secondaire 2.59 1.77, 3.83 <0.001
Technique/Professionnel 2.86 1.98, 4.17 <0.001
Supérieur 6.63 4.55, 9.80 <0.001
manquant 8.59 4.53, 16.6 <0.001
Pratique religieuse
Pratiquant regulier
Pratiquant occasionnel 0.98 0.68, 1.42 >0.9
Appartenance sans pratique 0.99 0.71, 1.40 >0.9
Ni croyance ni appartenance 0.81 0.55, 1.18 0.3
Rejet 0.68 0.39, 1.19 0.2
NSP ou NVPR 0.92 0.40, 2.02 0.8
Nombre d'heures passées devant la télévision par jour 0.89 0.83, 0.95 <0.001

1 OR = Odds Ratio, CI = Confidence Interval

Représentation graphique du modèle

Il est possible de représenter graphiquement les différents odds ratios. Pour cela, on va utiliser la fonction tidy de l’extension broom pour récupérer les coefficients du modèle sous la forme d’un tableau de données exploitable avec ggplot2. geom_errorbarh permets de représenter les intervalles de confiance sous forme de barres d’erreurs, geom_vline une ligne verticale au niveau x = 1, scale_x_log10 pour afficher l’axe des x de manière logarithmique, les odds ratios étant de nature multiplicative et non additive.

library(broom)
tmp <- tidy(reg, conf.int = TRUE, exponentiate = TRUE)
str(tmp)
tibble [15 x 7] (S3: tbl_df/tbl/data.frame)
 $ term     : chr [1:15] "(Intercept)" "sexeHomme" "grpage[25,45)" "grpage[45,65)" ...
 $ estimate : num [1:15] 0.45 1.552 0.657 0.338 0.251 ...
 $ std.error: num [1:15] 0.324 0.106 0.228 0.238 0.274 ...
 $ statistic: num [1:15] -2.46 4.15 -1.84 -4.57 -5.05 ...
 $ p.value  : num [1:15] 1.37e-02 3.39e-05 6.52e-02 4.97e-06 4.53e-07 ...
 $ conf.low : num [1:15] 0.238 1.261 0.419 0.212 0.146 ...
 $ conf.high: num [1:15] 0.847 1.912 1.027 0.538 0.429 ...
library(ggplot2)
ggplot(tmp) +
  aes(x = estimate, y = term, xmin = conf.low, xmax = conf.high) +
  geom_vline(xintercept = 1) +
  geom_errorbarh() +
  geom_point() +
  scale_x_log10()
Représentation graphique des odds ratios

La fonction ggcoef de l’extension GGally permet d’effectuer le graphique précédent directement à partir de notre modèle. Voir l’aide de cette fonction pour la liste complète des paramètres personnalisables.

library(GGally)
ggcoef(reg, exponentiate = TRUE)
La fonction ggcoef

Il est possible de combiner tidy_plus_plus avec ggcoef pour personnaliser un peu plus le résultat.

td <- tidy_plus_plus(reg, exponentiate = TRUE)
td$label <- forcats::fct_inorder(td$label) # Pour fixer l'ordre pour ggplot2
ggcoef(
  td,
  mapping = aes(y = label, x = estimate, colour = var_label),
  exponentiate = TRUE
) +
  labs(colour = "Variable") +
  # Pour afficher les étiquettes trop longues sur plusieurs lignes
  scale_colour_discrete(labels = scales::label_wrap(20)) +
  guides(colour = guide_legend(nrow = 3)) +
  theme(legend.position = "bottom")
Warning: Removed 4 rows containing missing values
(geom_errorbarh).

Une version améliorée de ggcoef est en cours de développement et sera prochainement disponible dans GGally

L’extension forestmodel propose de son côté une fonction forest_model qui, à partir d’un modèle, propose une représentation visuelle et tabulaire des coefficients.

library(forestmodel)
forest_model(reg)
Warning in recalculate_width_panels(panel_positions,
mapped_text = mapped_text, : Unable to resize forest panel
to be smaller than its heading; consider a smaller text size
La fonction forest_model

A la différence de ggcoef qui fonctionne avec la plupart des types de modèles (dont les modèles à effets mixtes ou ceux réalisés avec un plan d’échantillonnage complexe), forest_model ne fonctionne qu’avec les modèles les plus courants.

Représentation graphique des effets

L’extension effects propose une représentation graphique résumant les effets de chaque variable du modèle. Pour cela, il suffit d’appliquer la méthode plot au résultat de la fonction allEffects. Nous obtenons alors la figure ci-dessous.

library(effects)
plot(allEffects(reg))
Représentation graphique de l’effet de chaque variable du modèle logistique

Nous pouvons alternativement avoir recours à l’extension ggeffects3 et sa fonction ggeffect qui permettent de récupérer les résultats de effects dans un format utilisable avec ggplot2.

Ainsi, la fonction ggeffect, quand on lui précise un terme spécifique, produit un tableau de données avec les effets marginaux pour cette variable.

library(ggeffects)
ggeffect(reg, "sexe")

En combinant ce résultat avec plot, on obtient un graphique ggplot2 de l’effet en question.

plot(ggeffect(reg, "sexe"))
Effet du sexe représenté avec ggeffect

Si l’on ne précise pas de terme, ggeffect(reg) calcule les effets pour chaque variable du modèle et plot(ggeffect(reg)) renvoie une liste de graphiques. Il faut donc utiliser la fonction plot_grid de cowplot pour combiner ces graphiques en un seul (voir le chapitre dédié).

library(ggeffects)
cowplot::plot_grid(plotlist = plot(ggeffect(reg)))
Effet du modèles représentés avec ggeffect

On pourra noter la prise en compte par ggeffect des étiquettes de variables définies plus haut.

Matrice de confusion

Une manière de tester la qualité d’un modèle est le calcul d’une matrice de confusion, c’est-à-dire le tableau croisé des valeurs observées et celles des valeurs prédites en appliquant le modèle aux données d’origine.

La méthode predict avec l’argument type="response" permet d’appliquer notre modèle logistique à un tableau de données et renvoie pour chaque individu la probabilité qu’il ait vécu le phénomène étudié.

sport.pred <- predict(reg, type = "response", newdata = d)
head(sport.pred)
         1          2          3          4          5 
0.61241192 0.73414575 0.15982958 0.70350157 0.07293505 
         6 
0.34824228 

Or notre variable étudiée est de type binaire. Nous devons donc transformer nos probabilités prédites en une variable du type « oui / non ». Usuellement, les probabilités prédites seront réunies en deux groupes selon qu’elles soient supérieures ou inférieures à la moitié. La matrice de confusion est alors égale à :

table(sport.pred > 0.5, d$sport)
       
         Non  Oui
  FALSE 1076  384
  TRUE   199  336

Nous avons donc 583 (384+199) prédictions incorrectes sur un total de 1993, soit un taux de mauvais classement de 29,3 %.

Identifier les variables ayant un effet significatif

Les p-values associées aux odds ratios nous indique si un odd ratio est significativement différent de 1, par rapport à la modalité de référebce. Mais cela n’indique pas si globalement une variable a un effet significatif sur le modèle. Pour tester l’effet global sur un modèle, on peut avoir recours à la fonction drop1. Cette dernière va tour à tour supprimer chaque variable du modèle et réaliser une analyse de variance (ANOVA, voir fonction anova) pour voir si la variance change significativement.

drop1(reg, test = "Chisq")

Ainsi, dans le cas présent, la suppression de la variable relig ne modifie significativement pas le modèle, indiquant l’absence d’effet de cette variable.

Une fonction plus générique (i.e. fonctionnant avec une plus grande variété de modèles) est la fonction Anova de l’extension car.

library(car)
Anova(reg)

Si l’on a recours à tbl_regression, on peut facilement ajouter les p-valeurs globales avec add_global_p.

reg %>%
  tbl_regression(exponentiate = TRUE) %>%
  add_global_p(type = "II")
add_global_p: Global p-values for variable(s) `include = c("grpage", "etud",
"relig")` were calculated with
  `car::Anova(x$model_obj, type = "II")`
Characteristic OR1 95% CI1 p-value
Sexe
Femme
Homme 1.55 1.26, 1.91 <0.001
Groupe d'âges <0.001
[16,25)
[25,45) 0.66 0.42, 1.03
[45,65) 0.34 0.21, 0.54
[65,99] 0.25 0.15, 0.43
Niveau d'étude <0.001
Primaire
Secondaire 2.59 1.77, 3.83
Technique/Professionnel 2.86 1.98, 4.17
Supérieur 6.63 4.55, 9.80
manquant 8.59 4.53, 16.6
Pratique religieuse 0.5
Pratiquant regulier
Pratiquant occasionnel 0.98 0.68, 1.42
Appartenance sans pratique 0.99 0.71, 1.40
Ni croyance ni appartenance 0.81 0.55, 1.18
Rejet 0.68 0.39, 1.19
NSP ou NVPR 0.92 0.40, 2.02
Nombre d'heures passées devant la télévision par jour 0.89 0.83, 0.95 <0.001

1 OR = Odds Ratio, CI = Confidence Interval

Concernant le test réalisé dans le cadre d’une Anova, il existe trois tests différents que l’on présente comme le type 1, le type 2 et le type 3 (ou I, II et III). Pour une explication sur ces différents types, on pourra se référer (en anglais) à https://mcfromnz.wordpress.com/2011/03/02/anova-type-iiiiii-ss-explained/ ou encore http://md.psych.bio.uni-goettingen.de/mv/unit/lm_cat/lm_cat_unbal_ss_explained.html.

Le type I n’est pas recommandé dans le cas présent car il dépend de l’ordre dans lequel les différentes variables sont testées.

Lorsqu’il n’y a pas d’interaction dans un modèle (voir le chapitre sur les interactions), le type II serait à privilégier car plus puissant.

En présence d’interactions, il est conseillé d’avoir plutôt recours au type III. Cependant, en toute rigueur, pour utiliser le type III, il faut que les variables catégorielles soient codées en utilisant un contrastes dont la somme est nulle (un contrast de type somme ou polynomial). Or, par défaut, les variables catégorielles sont codées avec un contraste de type traitement (pour une explication sur les contrastes dans les modèles, voir en anglais cette page ou celle-ci).

Par défaut, Anova utilise le type II et add_global_p le type III. Dans les deux cas, il est possible de préciser le type de test avec type = "II" ou type = "III".

Dans le cas de notre exemple, un modèle simple sans interaction, le type de test ne change pas les résultats.

Anova(reg, type = "II")
Anova(reg, type = "III")

Sélection de modèles

Il est toujours tentant lorsque l’on recherche les facteurs associés à un phénomène d’inclure un nombre important de variables explicatives potentielles dans un mmodèle logistique. Cependant, un tel modèle n’est pas forcément le plus efficace et certaines variables n’auront probablement pas d’effet significatif sur la variable d’intérêt.

La technique de sélection descendante pas à pas est une approche visant à améliorer son modèle explicatif4. On réalise un premier modèle avec toutes les variables spécifiées, puis on regarde s’il est possible d’améliorer le modèle en supprimant une des variables du modèle. Si plusieurs variables permettent d’améliorer le modèle, on supprimera la variable dont la suppression améliorera le plus le modèle. Puis on recommence le même procédé pour voir si la suppression d’une seconde variable peut encore améliorer le modèle et ainsi de suite. Lorsque le modèle ne peut plus être améliorer par la suppresion d’une variable, on s’arrête.

Il faut également définir un critère pour déterminer la qualité d’un modèle. L’un des plus utilisés est le Akaike Information Criterion ou AIC. Plus l’AIC sera faible, meilleure sera le modèle.

La fonction step permet justement de sélectionner le meilleur modèle par une procédure pas à pas descendante basée sur la minimisation de l’AIC. La fonction affiche à l’écran les différentes étapes de la sélection et renvoie le modèle final.

reg2 <- step(reg)
Start:  AIC=2236.17
sport ~ sexe + grpage + etud + relig + heures.tv

            Df Deviance    AIC
- relig      5   2210.4 2230.4
<none>           2206.2 2236.2
- heures.tv  1   2219.6 2247.6
- sexe       1   2223.5 2251.5
- grpage     3   2259.0 2283.0
- etud       4   2330.0 2352.0

Step:  AIC=2230.4
sport ~ sexe + grpage + etud + heures.tv

            Df Deviance    AIC
<none>           2210.4 2230.4
- heures.tv  1   2224.0 2242.0
- sexe       1   2226.4 2244.4
- grpage     3   2260.6 2274.6
- etud       4   2334.3 2346.3

Le modèle initial a un AIC de 2235,9. À la première étape, il apparait que la suppression de la variable religion permet diminuer l’AIC à 2230,2. Lors de la seconde étape, toute suppression d’une autre variable ferait augmenter l’AIC. La procédure s’arrête donc.

Pour obtenir directement l’AIC d’un modèle donné, on peut utiliser la fonction AIC.

AIC(reg)
[1] 2236.173
AIC(reg2)
[1] 2230.404

On peut effectuer une analyse de variance ou ANOVA pour comparer les deux modèles avec la fonction anova.

anova(reg, reg2, test = "Chisq")

Il n’y a pas de différences significatives entre nos deux modèles. Autrement dit, notre second modèle explique tout autant de variance que notre premier modèle, tout en étant plus parcimonieux.

Une alternative à la fonction step est la fonction stepAIC de l’extension MASS qui fonctionne de la même manière. Si cela ne change rien aux régressions logistiques classiques, il arrive que pour certains types de modèle la méthode step ne soit pas disponible, mais que stepAIC puisse être utilisée à la place.

library(MASS)
reg2bis <- stepAIC(reg)
Start:  AIC=2236.17
sport ~ sexe + grpage + etud + relig + heures.tv

            Df Deviance    AIC
- relig      5   2210.4 2230.4
<none>           2206.2 2236.2
- heures.tv  1   2219.6 2247.6
- sexe       1   2223.5 2251.5
- grpage     3   2259.0 2283.0
- etud       4   2330.0 2352.0

Step:  AIC=2230.4
sport ~ sexe + grpage + etud + heures.tv

            Df Deviance    AIC
<none>           2210.4 2230.4
- heures.tv  1   2224.0 2242.0
- sexe       1   2226.4 2244.4
- grpage     3   2260.6 2274.6
- etud       4   2334.3 2346.3

Tableaux all-in-one

gtsummary

Nous avons déjà vu précédemment la fonction tbl_regression de l’extension gtsummary. Une vignette dédiée de l’extension explicite les possibilités de personnalisation des résultats. Par exemple add_global_p permet d’ajouter des p-valeurs globales pour chaque variable.

library(gtsummary)
theme_gtsummary_language("fr", decimal.mark = ",", big.mark = " ")
Setting `language: fr` theme
tbl_regression(reg, exponentiate = TRUE) %>%
  add_global_p(keep = TRUE)
add_global_p: Global p-values for variable(s) `include = c("grpage", "etud",
"relig")` were calculated with
  `car::Anova(x$model_obj, type = "III")`
Caractéristique OR1 95% CI1 p-value
Sexe
Femme
Homme 1,55 1,26 – 1,91 <0,001
Groupe d'âges <0,001
[16,25)
[25,45) 0,66 0,42 – 1,03 0,065
[45,65) 0,34 0,21 – 0,54 <0,001
[65,99] 0,25 0,15 – 0,43 <0,001
Niveau d'étude <0,001
Primaire
Secondaire 2,59 1,77 – 3,83 <0,001
Technique/Professionnel 2,86 1,98 – 4,17 <0,001
Supérieur 6,63 4,55 – 9,80 <0,001
manquant 8,59 4,53 – 16,6 <0,001
Pratique religieuse 0,5
Pratiquant regulier
Pratiquant occasionnel 0,98 0,68 – 1,42 >0,9
Appartenance sans pratique 0,99 0,71 – 1,40 >0,9
Ni croyance ni appartenance 0,81 0,55 – 1,18 0,3
Rejet 0,68 0,39 – 1,19 0,2
NSP ou NVPR 0,92 0,40 – 2,02 0,8
Nombre d'heures passées devant la télévision par jour 0,89 0,83 – 0,95 <0,001

1 OR = rapport de cotes, CI = intervalle de confiance

On peut remarquer que gtsummary (comme d’autres extensions présentées précédemment) a tenu compte des étiquettes de variables définies plus haut avec var_label de l’extension labelled (voir le chapitre sur les vecteurs labellisés).

Comme tbl_regression respose sur les extensions broom et broom.helpers, gtsummary peut en principe couvrir un plus grand nombre de modèles que finalfit ainsi qu’un plus grand nombre de cas particuliers (effets d’interactions, contrastes autres que traitement, paramètre polynomiaux définis avec poly.

tbl_merge permet de fusionner ensemble les résultats de plusieurs modèles.

tbl_merge(
  tbls = list(tbl_regression(reg), tbl_regression(reg2)),
  tab_spanner = c("Modèle complet", "Modèle réduit")
)
Caractéristique Modèle complet Modèle réduit
log(OR)1 95% CI1 p-value log(OR)1 95% CI1 p-value
Sexe
Femme
Homme 0,44 0,23 – 0,65 <0,001 0,42 0,21 – 0,62 <0,001
Groupe d'âges
[16,25)
[25,45) -0,42 -0,87 – 0,03 0,065 -0,39 -0,84 – 0,05 0,084
[45,65) -1,1 -1,6 – -0,62 <0,001 -1,0 -1,5 – -0,57 <0,001
[65,99] -1,4 -1,9 – -0,85 <0,001 -1,3 -1,8 – -0,78 <0,001
Niveau d'étude
Primaire
Secondaire 1,0 0,57 – 1,3 <0,001 0,93 0,55 – 1,3 <0,001
Technique/Professionnel 1,0 0,68 – 1,4 <0,001 1,0 0,67 – 1,4 <0,001
Supérieur 1,9 1,5 – 2,3 <0,001 1,9 1,5 – 2,3 <0,001
manquant 2,2 1,5 – 2,8 <0,001 2,1 1,5 – 2,8 <0,001
Pratique religieuse
Pratiquant regulier
Pratiquant occasionnel -0,02 -0,39 – 0,35 >0,9
Appartenance sans pratique -0,01 -0,35 – 0,34 >0,9
Ni croyance ni appartenance -0,22 -0,59 – 0,16 0,3
Rejet -0,38 -0,95 – 0,17 0,2
NSP ou NVPR -0,08 -0,92 – 0,70 0,8
Nombre d'heures passées devant la télévision par jour -0,12 -0,19 – -0,06 <0,001 -0,12 -0,19 – -0,06 <0,001

1 OR = rapport de cotes, CI = intervalle de confiance

L’extension gtsummary fournit également la fonction tbl_summary pour effectuer des tris à plats et/ou un tri croisé.

d %>%
  dplyr::select(sport, sexe, grpage, etud, relig, heures.tv) %>%
  tbl_summary()
Caractéristique N = 2 0001
Pratique du sport ?
Non 1 277 (64%)
Oui 723 (36%)
Sexe
Femme 1 101 (55%)
Homme 899 (45%)
Groupe d'âges
[16,25) 169 (8,5%)
[25,45) 706 (35%)
[45,65) 745 (37%)
[65,99] 380 (19%)
Niveau d'étude
Primaire 466 (23%)
Secondaire 387 (19%)
Technique/Professionnel 594 (30%)
Supérieur 441 (22%)
manquant 112 (5,6%)
Pratique religieuse
Pratiquant regulier 266 (13%)
Pratiquant occasionnel 442 (22%)
Appartenance sans pratique 760 (38%)
Ni croyance ni appartenance 399 (20%)
Rejet 93 (4,7%)
NSP ou NVPR 40 (2,0%)
Nombre d'heures passées devant la télévision par jour 2,00 (1,00 – 3,00)
Manquant 5

1 Statistique présentée: n (%); Médiane (EI)

d %>%
  dplyr::select(sport, sexe, grpage, etud, relig, heures.tv) %>%
  tbl_summary(by = "sport", percent = "row") %>%
  add_overall(last = TRUE) %>%
  add_p()
Caractéristique Non, N = 1 2771 Oui, N = 7231 Total, N = 2 0001 p-value2
Sexe <0,001
Femme 747 (68%) 354 (32%) 1 101 (100%)
Homme 530 (59%) 369 (41%) 899 (100%)
Groupe d'âges <0,001
[16,25) 58 (34%) 111 (66%) 169 (100%)
[25,45) 359 (51%) 347 (49%) 706 (100%)
[45,65) 541 (73%) 204 (27%) 745 (100%)
[65,99] 319 (84%) 61 (16%) 380 (100%)
Niveau d'étude <0,001
Primaire 416 (89%) 50 (11%) 466 (100%)
Secondaire 270 (70%) 117 (30%) 387 (100%)
Technique/Professionnel 378 (64%) 216 (36%) 594 (100%)
Supérieur 186 (42%) 255 (58%) 441 (100%)
manquant 27 (24%) 85 (76%) 112 (100%)
Pratique religieuse 0,14
Pratiquant regulier 182 (68%) 84 (32%) 266 (100%)
Pratiquant occasionnel 295 (67%) 147 (33%) 442 (100%)
Appartenance sans pratique 473 (62%) 287 (38%) 760 (100%)
Ni croyance ni appartenance 239 (60%) 160 (40%) 399 (100%)
Rejet 60 (65%) 33 (35%) 93 (100%)
NSP ou NVPR 28 (70%) 12 (30%) 40 (100%)
Nombre d'heures passées devant la télévision par jour 2,00 (1,00 – 3,00) 2,00 (1,00 – 3,00) 2,00 (1,00 – 3,00) <0,001
Manquant 2 3 5

1 Statistique présentée: n (%); Médiane (EI)

2 Test statistique réalisé: test du khi-deux d'indépendance; test de Wilcoxon-Mann-Whitney

Il est à noter que tbl_regression sait prendre en compte les effets d’interactions (voir ci-après).

finalfit

L’extension finalfit fournit une fonction finalfit du type all-in-one qui calcule un tableau avec les tris croisés, les odds ratios univariés et un modèle multivarié.

Il faut d’abord définir la variable dépendante et les variables explicatives.

dep <- "sport"
vars <- c("sexe", "grpage", "etud", "relig", "heures.tv")

Une première fonction summary_factorlist fournit un tableau descriptif avec, si l’option p = TRUE est indiquée, des tests de comparaisons (ici des tests du Chi²).

library(finalfit)
tab <- summary_factorlist(d, dep, vars, p = TRUE, add_dependent_label = TRUE)
tab

On peut remarquer que finalfit a tenu compte des étiquettes de variables définies plus haut avec var_label de l’extension labelled (voir le chapitre sur les vecteurs labellisés).

On peut associer le résultat avec la fonction kable de knitr pour un rendu plus esthétique lorsque l’on produit un rapport Rmarkdown (voir le chapitre dédié aux rapports automatisés).

knitr::kable(tab, row.names = FALSE)
Dependent: Pratique du sport ? Non Oui p
Sexe Femme 747 (58.5) 354 (49.0) <0.001
Homme 530 (41.5) 369 (51.0)
Groupe d’âges [16,25) 58 (4.5) 111 (15.4) <0.001
[25,45) 359 (28.1) 347 (48.0)
[45,65) 541 (42.4) 204 (28.2)
[65,99] 319 (25.0) 61 (8.4)
Niveau d’étude Primaire 416 (32.6) 50 (6.9) <0.001
Secondaire 270 (21.1) 117 (16.2)
Technique/Professionnel 378 (29.6) 216 (29.9)
Supérieur 186 (14.6) 255 (35.3)
manquant 27 (2.1) 85 (11.8)
Pratique religieuse Pratiquant regulier 182 (14.3) 84 (11.6) 0.144
Pratiquant occasionnel 295 (23.1) 147 (20.3)
Appartenance sans pratique 473 (37.0) 287 (39.7)
Ni croyance ni appartenance 239 (18.7) 160 (22.1)
Rejet 60 (4.7) 33 (4.6)
NSP ou NVPR 28 (2.2) 12 (1.7)
Nombre d’heures passées devant la télévision par jour Mean (SD) 2.5 (1.9) 1.8 (1.4) <0.001

La fonction finalfit, quant à elle, calcule à la fois les odds ratios univariés (modèles logistiques avec une seule variable inclue à la fois) et un modèle complet, présentant le tout dans un tableau synthétique.

tab <- finalfit(d, dep, vars)
knitr::kable(tab, row.names = FALSE)
Dependent: Pratique du sport ? Non Oui OR (univariable) OR (multivariable)
Sexe Femme 747 (67.8) 354 (32.2) - -
Homme 530 (59.0) 369 (41.0) 1.47 (1.22-1.77, p<0.001) 1.55 (1.26-1.91, p<0.001)
Groupe d’âges [16,25) 58 (34.3) 111 (65.7) - -
[25,45) 359 (50.8) 347 (49.2) 0.51 (0.35-0.71, p<0.001) 0.66 (0.42-1.03, p=0.065)
[45,65) 541 (72.6) 204 (27.4) 0.20 (0.14-0.28, p<0.001) 0.34 (0.21-0.54, p<0.001)
[65,99] 319 (83.9) 61 (16.1) - -
Niveau d’étude Primaire 416 (89.3) 50 (10.7) - -
Secondaire 270 (69.8) 117 (30.2) 3.61 (2.52-5.23, p<0.001) 2.59 (1.77-3.83, p<0.001)
Technique/Professionnel 378 (63.6) 216 (36.4) 4.75 (3.42-6.72, p<0.001) 2.86 (1.98-4.17, p<0.001)
Supérieur 186 (42.2) 255 (57.8) 11.41 (8.11-16.31, p<0.001) 6.63 (4.55-9.80, p<0.001)
manquant 27 (24.1) 85 (75.9) 26.19 (15.74-44.90, p<0.001) 8.59 (4.53-16.59, p<0.001)
Pratique religieuse Pratiquant regulier 182 (68.4) 84 (31.6) - -
Pratiquant occasionnel 295 (66.7) 147 (33.3) 1.08 (0.78-1.50, p=0.644) 0.98 (0.68-1.42, p=0.908)
Appartenance sans pratique 473 (62.2) 287 (37.8) 1.31 (0.98-1.78, p=0.071) 0.99 (0.71-1.40, p=0.969)
Ni croyance ni appartenance 239 (59.9) 160 (40.1) 1.45 (1.05-2.02, p=0.026) 0.81 (0.55-1.18, p=0.265)
Rejet 60 (64.5) 33 (35.5) 1.19 (0.72-1.95, p=0.489) 0.68 (0.39-1.19, p=0.180)
NSP ou NVPR 28 (70.0) 12 (30.0) 0.93 (0.44-1.88, p=0.841) 0.92 (0.40-2.02, p=0.838)
Nombre d’heures passées devant la télévision par jour Mean (SD) 2.5 (1.9) 1.8 (1.4) 0.79 (0.74-0.84, p<0.001) 0.89 (0.83-0.95, p<0.001)
NA NA NA NA 0.10 (0.07-0.15, p<0.001) 0.25 (0.15-0.43, p<0.001)

Par défaut, toutes les variables explicatives fournies sont retenues dans le modèle affiché. Si on ne souhaite inclure que certaines variables dans le modèle mutivarié (parce que l’on aura précédemment réalisé une procédure step), il faudra préciser séparément les variables du modèle multivarié.

vars_multi <- c("sexe", "grpage", "etud", "heures.tv")
tab <- finalfit(d, dep, vars, explanatory_multi = vars_multi)
knitr::kable(tab, row.names = FALSE)
Dependent: Pratique du sport ? Non Oui OR (univariable) OR (multivariable)
Sexe Femme 747 (67.8) 354 (32.2) - -
Homme 530 (59.0) 369 (41.0) 1.47 (1.22-1.77, p<0.001) 1.52 (1.24-1.87, p<0.001)
Groupe d’âges [16,25) 58 (34.3) 111 (65.7) - -
[25,45) 359 (50.8) 347 (49.2) 0.51 (0.35-0.71, p<0.001) 0.68 (0.43-1.06, p=0.084)
[45,65) 541 (72.6) 204 (27.4) 0.20 (0.14-0.28, p<0.001) 0.36 (0.23-0.57, p<0.001)
[65,99] 319 (83.9) 61 (16.1) - -
Niveau d’étude Primaire 416 (89.3) 50 (10.7) - -
Secondaire 270 (69.8) 117 (30.2) 3.61 (2.52-5.23, p<0.001) 2.54 (1.73-3.75, p<0.001)
Technique/Professionnel 378 (63.6) 216 (36.4) 4.75 (3.42-6.72, p<0.001) 2.81 (1.95-4.10, p<0.001)
Supérieur 186 (42.2) 255 (57.8) 11.41 (8.11-16.31, p<0.001) 6.55 (4.50-9.66, p<0.001)
manquant 27 (24.1) 85 (75.9) 26.19 (15.74-44.90, p<0.001) 8.54 (4.51-16.47, p<0.001)
Pratique religieuse Pratiquant regulier 182 (68.4) 84 (31.6) - -
Pratiquant occasionnel 295 (66.7) 147 (33.3) 1.08 (0.78-1.50, p=0.644) -
Appartenance sans pratique 473 (62.2) 287 (37.8) 1.31 (0.98-1.78, p=0.071) -
Ni croyance ni appartenance 239 (59.9) 160 (40.1) 1.45 (1.05-2.02, p=0.026) -
Rejet 60 (64.5) 33 (35.5) 1.19 (0.72-1.95, p=0.489) -
NSP ou NVPR 28 (70.0) 12 (30.0) 0.93 (0.44-1.88, p=0.841) -
Nombre d’heures passées devant la télévision par jour Mean (SD) 2.5 (1.9) 1.8 (1.4) 0.79 (0.74-0.84, p<0.001) 0.89 (0.83-0.95, p<0.001)
NA NA NA NA 0.10 (0.07-0.15, p<0.001) 0.27 (0.16-0.46, p<0.001)

On pourra se référer à l’aide de la fonction finalfit pour d’autres exemples.

L’extension finalfit propose aussi une fonction or_plot pour présenter les odd ratios obtenus sous forme de graphique.

var_label(d$heures.tv) <- "Nombre d'heures\nde TV par jour"
or_plot(d, dep, vars_multi)
Waiting for profiling to be done...
Waiting for profiling to be done...
Waiting for profiling to be done...
Warning: Removed 4 rows containing missing values
(geom_errorbarh).
Graphique des odds ratios obtenu avec or_plot

ATTENTION : or_plot n’est pas compatible avec les effets d’interactions (cf. ci-dessous).

Effets d’interaction dans le modèle

Voir le chapitre dédié aux effets d’interaction.

Multicolinéarité

Voir le chapitre dédié.

Régression logistique multinomiale

La régression logistique multinomiale est une extension de la régression logistique aux variables qualitatives à trois modalités ou plus. Dans ce cas de figure, chaque modalité de la variable d’intérêt sera comparée à la modalité de réference. Les odds ratio seront donc exprimés par rapport à cette dernière.

Nous allons prendre pour exemple la variable trav.satisf, à savoir la satisfaction ou l’insatisfaction au travail.

freq(d$trav.satisf)

Nous allons choisir comme modalité de référence la position intermédiaire, à savoir l’« équilibre ».

d$trav.satisf <- relevel(d$trav.satisf, "Equilibre")

Enfin, nous allons aussi en profiter pour raccourcir les étiquettes de la variable trav.imp :

levels(d$trav.imp) <- c("Le plus", "Aussi", "Moins", "Peu")

Pour calculer un modèle logistique multinomial, nous allons utiliser la fonction multinom de l’extension nnet5. La syntaxe de multinom est similaire à celle de glm, le paramètre family en moins.

library(nnet)
regm <- multinom(trav.satisf ~ sexe + etud + grpage + trav.imp, data = d)
# weights:  39 (24 variable)
initial  value 1151.345679 
iter  10 value 977.348901
iter  20 value 969.849189
iter  30 value 969.522965
final  value 969.521855 
converged

Comme pour la régression logistique, il est possible de réaliser une sélection pas à pas descendante :

regm2 <- step(regm)
Start:  AIC=1987.04
trav.satisf ~ sexe + etud + grpage + trav.imp

trying - sexe 
# weights:  36 (22 variable)
initial  value 1151.345679 
iter  10 value 978.538886
iter  20 value 970.453555
iter  30 value 970.294459
final  value 970.293988 
converged
trying - etud 
# weights:  27 (16 variable)
initial  value 1151.345679 
iter  10 value 987.907714
iter  20 value 981.785467
iter  30 value 981.762800
final  value 981.762781 
converged
trying - grpage 
# weights:  30 (18 variable)
initial  value 1151.345679 
iter  10 value 979.485430
iter  20 value 973.175923
final  value 973.172389 
converged
trying - trav.imp 
# weights:  30 (18 variable)
initial  value 1151.345679 
iter  10 value 998.803976
iter  20 value 994.417973
iter  30 value 994.378914
final  value 994.378869 
converged
           Df      AIC
- grpage   18 1982.345
- sexe     22 1984.588
<none>     24 1987.044
- etud     16 1995.526
- trav.imp 18 2024.758
# weights:  30 (18 variable)
initial  value 1151.345679 
iter  10 value 979.485430
iter  20 value 973.175923
final  value 973.172389 
converged

Step:  AIC=1982.34
trav.satisf ~ sexe + etud + trav.imp

trying - sexe 
# weights:  27 (16 variable)
initial  value 1151.345679 
iter  10 value 976.669670
iter  20 value 973.928385
iter  20 value 973.928377
iter  20 value 973.928377
final  value 973.928377 
converged
trying - etud 
# weights:  18 (10 variable)
initial  value 1151.345679 
iter  10 value 988.413720
final  value 985.085797 
converged
trying - trav.imp 
# weights:  21 (12 variable)
initial  value 1151.345679 
iter  10 value 1001.517287
final  value 998.204280 
converged
           Df      AIC
- sexe     16 1979.857
<none>     18 1982.345
- etud     10 1990.172
- trav.imp 12 2020.409
# weights:  27 (16 variable)
initial  value 1151.345679 
iter  10 value 976.669670
iter  20 value 973.928385
iter  20 value 973.928377
iter  20 value 973.928377
final  value 973.928377 
converged

Step:  AIC=1979.86
trav.satisf ~ etud + trav.imp

trying - etud 
# weights:  15 (8 variable)
initial  value 1151.345679 
iter  10 value 986.124104
final  value 986.034023 
converged
trying - trav.imp 
# weights:  18 (10 variable)
initial  value 1151.345679 
iter  10 value 1000.225356
final  value 998.395273 
converged
           Df      AIC
<none>     16 1979.857
- etud      8 1988.068
- trav.imp 10 2016.791

La plupart des fonctions vues précédemment fonctionnent :

summary(regm2)
Call:
multinom(formula = trav.satisf ~ etud + trav.imp, data = d)

Coefficients:
               (Intercept) etudSecondaire
Satisfaction    -0.1110996     0.04916210
Insatisfaction  -1.1213760    -0.09737523
               etudTechnique/Professionnel etudSupérieur
Satisfaction                    0.07793241    0.69950061
Insatisfaction                  0.08392603    0.07755307
               etudmanquant trav.impAussi trav.impMoins
Satisfaction    -0.53841577     0.2578973    -0.1756206
Insatisfaction  -0.04364055    -0.2279774    -0.5330349
               trav.impPeu
Satisfaction    -0.5995051
Insatisfaction   1.3401509

Std. Errors:
               (Intercept) etudSecondaire
Satisfaction     0.4520902      0.2635573
Insatisfaction   0.6516992      0.3999875
               etudTechnique/Professionnel etudSupérieur
Satisfaction                     0.2408483     0.2472571
Insatisfaction                   0.3579684     0.3831110
               etudmanquant trav.impAussi trav.impMoins
Satisfaction      0.5910993     0.4260623     0.4115818
Insatisfaction    0.8407592     0.6213781     0.5941721
               trav.impPeu
Satisfaction     0.5580115
Insatisfaction   0.6587383

Residual Deviance: 1947.857 
AIC: 1979.857 
odds.ratio(regm2)

De même, il est possible de calculer la matrice de confusion :

table(predict(regm2, newdata = d), d$trav.satisf)
                
                 Equilibre Satisfaction Insatisfaction
  Equilibre            262          211             49
  Satisfaction         171          258             45
  Insatisfaction        18           11             23

La fonction tidy peut s’appliquer au résultat de multinom :

library(broom)
tidy(regm2, exponentiate = TRUE, conf.int = TRUE)

On notera la présence d’une colonne supplémentaire, y.level. De fait, la fonction ggcoef ne peut s’appliquer directement, car les coefficients vont se supperposer.

ggcoef(regm2, exponentiate = TRUE)
À ne pas faire : appliquer directment ggcoef

On a deux solutions possibles. Pour la première, la plus simple, il suffit d’ajouter des facettes avec facet_grid.

ggcoef(regm2, exponentiate = TRUE) + facet_grid(~y.level)
ggcoef avec facet_grid

Pour la seconde, on va réaliser un graphique personnalisé, sur la même logique que ggcoef, décalant les points grâce à position_dodge.

ggplot(tidy(regm2, exponentiate = T, conf.int = TRUE)) +
  aes(x = term, y = estimate, ymin = conf.low, ymax = conf.high, color = y.level) +
  geom_hline(yintercept = 1, color = "gray25", linetype = "dotted") +
  geom_errorbar(position = position_dodge(0.5), width = 0) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_y_log10() +
  coord_flip()
Odds ratio d’un modèle multinomial

Il est possible de représenter les effets marginaux du modèle avec la fonction allEffects de l’extension effects.

library(effects)
plot(allEffects(regm2))
Effets marginaux du modèle multinomial

Une alternative est d’avoir recours à la fonction ggeffect de l’extension ggeffects.

library(ggeffects)
plot(ggeffect(regm2, "trav.imp"))

plot(ggeffect(regm2, "etud"))
Représentation alternative des effets marginaux du modèle multinomial

Régression logistique ordinale

La régression logistique ordinale s’applique lorsque la variable à expliquer possède trois ou plus modalités qui sont ordonnées (par exemple : modéré, moyen, fort).

L’extension la plus utilisée pour réaliser des modèles ordinaux est ordinal et sa fonction clm. Il est même possible de réaliser des modèles ordinaux avec des effets aléatoires (modèles mixtes) à l’aide de la fonction clmm.

Pour une bonne introduction à l’extension ordinal, on pourra se référer au tutoriel officiel (en anglais) : https://cran.r-project.org/web/packages/ordinal/vignettes/clm_tutorial.pdf.

Une autre introduction pertinente (en français) et utilisant cette fois-ci l’extention VGAM et sa fonction vglm est disponible sur le site de l’université de Lyon : https://eric.univ-lyon2.fr/~ricco/cours/didacticiels/data-mining/didacticiel_Reg_Logistique_Polytomique_Ordinale.pdf.

On va reprendre l’exemple précédent puisque la variable trav.satisf est une variable ordonnée.

freq(d$trav.satisf)

ATTENTION : Dans le cas d’une régression logistique ordinale, il importante que les niveaux du facteur soient classés selon leur ordre hiéarchique (du plus faible au plus fort). On va dès lors recoder notre variable à expliquer.

d$trav.satisf <- factor(d$trav.satisf, c("Insatisfaction", "Equilibre", "Satisfaction"), ordered = TRUE)
freq(d$trav.satisf)
library(ordinal)
rego <- clm(trav.satisf ~ sexe + etud + trav.imp, data = d)
summary(rego)
formula: trav.satisf ~ sexe + etud + trav.imp
data:    d

 link  threshold nobs logLik  AIC     niter max.grad
 logit flexible  1048 -978.61 1977.23 5(0)  5.41e-09
 cond.H 
 3.9e+02

Coefficients:
                            Estimate Std. Error z value
sexeHomme                   -0.16141    0.12215  -1.321
etudSecondaire               0.05558    0.23220   0.239
etudTechnique/Professionnel  0.03373    0.21210   0.159
etudSupérieur                0.61336    0.21972   2.792
etudmanquant                -0.45555    0.48761  -0.934
trav.impAussi                0.35104    0.38578   0.910
trav.impMoins                0.02616    0.37174   0.070
trav.impPeu                 -1.66062    0.46204  -3.594
                            Pr(>|z|)    
sexeHomme                   0.186369    
etudSecondaire              0.810819    
etudTechnique/Professionnel 0.873660    
etudSupérieur               0.005245 ** 
etudmanquant                0.350174    
trav.impAussi               0.362857    
trav.impMoins               0.943896    
trav.impPeu                 0.000325 ***
---
Signif. codes:  
0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Threshold coefficients:
                         Estimate Std. Error z value
Insatisfaction|Equilibre  -2.0226     0.4189  -4.829
Equilibre|Satisfaction     0.3391     0.4113   0.825
(952 observations deleted due to missingness)

Une fois encore, il est possible de faire une sélection descendante pas à pas.

rego2 <- step(rego)
Start:  AIC=1977.23
trav.satisf ~ sexe + etud + trav.imp

           Df    AIC
- sexe      1 1977.0
<none>        1977.2
- etud      4 1990.6
- trav.imp  3 2013.2

Step:  AIC=1976.97
trav.satisf ~ etud + trav.imp

           Df    AIC
<none>        1977.0
- etud      4 1990.6
- trav.imp  3 2011.6

L’extension broom propose une méthode tidy pour les objets clm.

tidy(rego2, exponentiate = TRUE, conf.int = TRUE)

La méthode tidy étant disponible, on peut utiliser ggcoef et tbl_regression.

library(JLutils)
library(GGally)
ggcoef(rego2, exponentiate = TRUE)
Warning: Removed 2 rows containing missing values
(geom_errorbarh).
Coefficients du modèle ordinal
tbl_regression(rego, exponentiate = TRUE)
Caractéristique exp(Beta) 95% CI1 p-value
Sexe
Femme
Homme 0,85 0,67 – 1,08 0,2
Niveau d'étude
Primaire
Secondaire 1,06 0,67 – 1,67 0,8
Technique/Professionnel 1,03 0,68 – 1,57 0,9
Supérieur 1,85 1,20 – 2,84 0,005
manquant 0,63 0,24 – 1,66 0,4
trav.imp
Le plus
Aussi 1,42 0,66 – 3,03 0,4
Moins 1,03 0,49 – 2,13 >0,9
Peu 0,19 0,08 – 0,47 <0,001

1 CI = intervalle de confiance

Données pondérées et l’extension survey

Lorsque l’on utilise des données pondérées, on aura recours à l’extension survey6.

Préparons des données d’exemple :

library(survey)
dw <- svydesign(ids = ~1, data = d, weights = ~poids)

Régression logistique binaire

L’extension survey fournit une fonction svyglm permettant de calculer un modèle statistique tout en prenant en compte le plan d’échantillonnage spécifié. La syntaxe de svyglm est proche de celle de glm. Cependant, le cadre d’une régression logistique, il est nécessaire d’utiliser family = quasibinomial() afin d’éviter un message d’erreur indiquant un nombre non entier de succès :

reg <- svyglm(sport ~ sexe + age + relig + heures.tv, dw, family = binomial())
Warning in eval(family$initialize): non-integer #successes
in a binomial glm!
reg <- svyglm(sport ~ sexe + age + relig + heures.tv, dw, family = quasibinomial())
reg
Independent Sampling design (with replacement)
svydesign(ids = ~1, data = d, weights = ~poids)

Call:  svyglm(formula = sport ~ sexe + age + relig + heures.tv, design = dw, 
    family = quasibinomial())

Coefficients:
                     (Intercept)  
                         1.53590  
                       sexeHomme  
                         0.36526  
                             age  
                        -0.04127  
     religPratiquant occasionnel  
                         0.05577  
 religAppartenance sans pratique  
                         0.16367  
religNi croyance ni appartenance  
                         0.03988  
                      religRejet  
                        -0.14862  
                religNSP ou NVPR  
                        -0.22682  
                       heures.tv  
                        -0.18204  

Degrees of Freedom: 1994 Total (i.e. Null);  1986 Residual
  (5 observations deleted due to missingness)
Null Deviance:      2672 
Residual Deviance: 2378     AIC: NA

Le résultat obtenu est similaire à celui de glm et l’on peut utiliser sans problème les fonctions coef, confint, odds.ratio, predict ou encore tidy.

odds.ratio(reg)
library(broom)
tidy(reg, exponentiate = TRUE, conf.int = TRUE)
tbl_regression(reg, exponentiate = TRUE)
Caractéristique exp(Beta) 95% CI1 p-value
Sexe
Femme
Homme 1,44 1,12 – 1,85 0,004
age 0,96 0,95 – 0,97 <0,001
Pratique religieuse
Pratiquant regulier
Pratiquant occasionnel 1,06 0,66 – 1,70 0,8
Appartenance sans pratique 1,18 0,76 – 1,83 0,5
Ni croyance ni appartenance 1,04 0,65 – 1,68 0,9
Rejet 0,86 0,43 – 1,74 0,7
NSP ou NVPR 0,80 0,32 – 1,96 0,6
Nombre d'heures de TV par jour 0,83 0,77 – 0,90 <0,001

1 CI = intervalle de confiance

Dans ses dernières versions, survey fournit une méthode AIC.svyglm permettant d’estimer un AIC sur un modèle calculé avec svyglm. Il est dès lors possible d’utiliser la fonction step pour réaliser une sélection descendante pas à pas.

L’extension effects n’est quant à elle pas compatible avec svyglm7.

Régression multinomiale

L’extension survey ne fournit pas de fonction adaptée aux régressions multinomiales. Cependant, il est possible d’en réaliser une en ayant recours à des poids de réplication, comme suggéré par Thomas Lumley dans son ouvrage Complex Surveys: A Guide to Analysis Using R. Thomas Lumley est par ailleurs l’auteur de l’extension survey.

L’extension svrepmisc disponible sur GitHub fournit quelques fonctions facilitant l’utilisation des poids de réplication avec survey. Pour l’installer, on utilisera le code ci-dessous :

devtools::install_github("carlganz/svrepmisc")

En premier lieu, il faut définir le design de notre tableau de données puis calculer des poids de réplication.

library(survey)
dw <- svydesign(ids = ~1, data = d, weights = ~poids)
dwr <- as.svrepdesign(dw, type = "bootstrap", replicates = 100)

Il faut prévoir un nombre de replicates suffisant pour calculer ultérieurement les intervalles de confiance des coefficients. Plus ce nombre est élevé, plus précise sera l’estimation de la variance et donc des valeurs p et des intervalles de confiance. Cependant, plus ce nombre est élevé, plus le temps de calcul sera important.

svrepmisc fournit une fonction svymultinom pour le calcul d’une régression multinomiale avec des poids de réplication.

library(svrepmisc)
regm <- svymultinom(trav.satisf ~ sexe + etud + grpage + trav.imp, design = dwr)

svrepmisc fournit également des méthodes confint et tidy. Il est également possible d’utiliser ggcoef.

regm
                                         Coefficient
Equilibre.(Intercept)                        0.93947
Satisfaction.(Intercept)                     0.74127
Equilibre.sexeHomme                         -0.24304
Satisfaction.sexeHomme                      -0.27381
Equilibre.etudSecondaire                    -0.41802
Satisfaction.etudSecondaire                 -0.26579
Equilibre.etudTechnique/Professionnel       -0.47708
Satisfaction.etudTechnique/Professionnel    -0.23585
Equilibre.etudSupérieur                     -0.57579
Satisfaction.etudSupérieur                   0.36801
Equilibre.etudmanquant                      -0.32346
Satisfaction.etudmanquant                   -0.65343
Equilibre.grpage[25,45)                      0.60710
Satisfaction.grpage[25,45)                   0.46941
Equilibre.grpage[45,65)                      0.57989
Satisfaction.grpage[45,65)                   0.52873
Equilibre.grpage[65,99]                     -3.20673
Satisfaction.grpage[65,99]                  11.60092
Equilibre.trav.impAussi                      0.42551
Satisfaction.trav.impAussi                   0.54156
Equilibre.trav.impMoins                      0.73727
Satisfaction.trav.impMoins                   0.66621
Equilibre.trav.impPeu                       -1.54722
Satisfaction.trav.impPeu                    -1.47191
                                               SE t value
Equilibre.(Intercept)                     3.01958  0.3111
Satisfaction.(Intercept)                  3.04837  0.2432
Equilibre.sexeHomme                       0.24073 -1.0096
Satisfaction.sexeHomme                    0.26877 -1.0187
Equilibre.etudSecondaire                  0.63395 -0.6594
Satisfaction.etudSecondaire               0.56432 -0.4710
Equilibre.etudTechnique/Professionnel     0.59969 -0.7955
Satisfaction.etudTechnique/Professionnel  0.58244 -0.4049
Equilibre.etudSupérieur                   0.66150 -0.8704
Satisfaction.etudSupérieur                0.63867  0.5762
Equilibre.etudmanquant                    6.46755 -0.0500
Satisfaction.etudmanquant                 6.49593 -0.1006
Equilibre.grpage[25,45)                   0.58980  1.0293
Satisfaction.grpage[25,45)                0.60105  0.7810
Equilibre.grpage[45,65)                   0.67281  0.8619
Satisfaction.grpage[45,65)                0.67497  0.7833
Equilibre.grpage[65,99]                  19.28257 -0.1663
Satisfaction.grpage[65,99]               22.27413  0.5208
Equilibre.trav.impAussi                   2.82794  0.1505
Satisfaction.trav.impAussi                2.83256  0.1912
Equilibre.trav.impMoins                   2.89134  0.2550
Satisfaction.trav.impMoins                2.91849  0.2283
Equilibre.trav.impPeu                     2.97380 -0.5203
Satisfaction.trav.impPeu                  2.92892 -0.5025
                                         Pr(>|t|)
Equilibre.(Intercept)                      0.7566
Satisfaction.(Intercept)                   0.8085
Equilibre.sexeHomme                        0.3159
Satisfaction.sexeHomme                     0.3116
Equilibre.etudSecondaire                   0.5116
Satisfaction.etudSecondaire                0.6390
Equilibre.etudTechnique/Professionnel      0.4288
Satisfaction.etudTechnique/Professionnel   0.6867
Equilibre.etudSupérieur                    0.3868
Satisfaction.etudSupérieur                 0.5662
Equilibre.etudmanquant                     0.9602
Satisfaction.etudmanquant                  0.9201
Equilibre.grpage[25,45)                    0.3066
Satisfaction.grpage[25,45)                 0.4372
Equilibre.grpage[45,65)                    0.3915
Satisfaction.grpage[45,65)                 0.4359
Equilibre.grpage[65,99]                    0.8684
Satisfaction.grpage[65,99]                 0.6040
Equilibre.trav.impAussi                    0.8808
Satisfaction.trav.impAussi                 0.8489
Equilibre.trav.impMoins                    0.7994
Satisfaction.trav.impMoins                 0.8200
Equilibre.trav.impPeu                      0.6044
Satisfaction.trav.impPeu                   0.6167
confint(regm)
                                               2.5 %
Equilibre.(Intercept)                     -5.0745416
Satisfaction.(Intercept)                  -5.3300846
Equilibre.sexeHomme                       -0.7224887
Satisfaction.sexeHomme                    -0.8091081
Equilibre.etudSecondaire                  -1.6806363
Satisfaction.etudSecondaire               -1.3897409
Equilibre.etudTechnique/Professionnel     -1.6714699
Satisfaction.etudTechnique/Professionnel  -1.3958788
Equilibre.etudSupérieur                   -1.8932861
Satisfaction.etudSupérieur                -0.9040006
Equilibre.etudmanquant                   -13.2047087
Satisfaction.etudmanquant                -13.5912046
Equilibre.grpage[25,45)                   -0.5675908
Satisfaction.grpage[25,45)                -0.7276896
Equilibre.grpage[45,65)                   -0.7601272
Satisfaction.grpage[45,65)                -0.8155905
Equilibre.grpage[65,99]                  -41.6113020
Satisfaction.grpage[65,99]               -32.7618590
Equilibre.trav.impAussi                   -5.2068246
Satisfaction.trav.impAussi                -5.0999615
Equilibre.trav.impMoins                   -5.0213396
Satisfaction.trav.impMoins                -5.1464707
Equilibre.trav.impPeu                     -7.4700575
Satisfaction.trav.impPeu                  -7.3053547
                                             97.5 %
Equilibre.(Intercept)                     6.9534790
Satisfaction.(Intercept)                  6.8126236
Equilibre.sexeHomme                       0.2364058
Satisfaction.sexeHomme                    0.2614955
Equilibre.etudSecondaire                  0.8445915
Satisfaction.etudSecondaire               0.8581514
Equilibre.etudTechnique/Professionnel     0.7173089
Satisfaction.etudTechnique/Professionnel  0.9241718
Equilibre.etudSupérieur                   0.7417093
Satisfaction.etudSupérieur                1.6400246
Equilibre.etudmanquant                   12.5577894
Satisfaction.etudmanquant                12.2843408
Equilibre.grpage[25,45)                   1.7817926
Satisfaction.grpage[25,45)                1.6665011
Equilibre.grpage[45,65)                   1.9199049
Satisfaction.grpage[45,65)                1.8730496
Equilibre.grpage[65,99]                  35.1978323
Satisfaction.grpage[65,99]               55.9636978
Equilibre.trav.impAussi                   6.0578454
Satisfaction.trav.impAussi                6.1830864
Equilibre.trav.impMoins                   6.4958711
Satisfaction.trav.impMoins                6.4788810
Equilibre.trav.impPeu                     4.3756212
Satisfaction.trav.impPeu                  4.3615289
library(broom)
tidy(regm, exponentiate = TRUE, conf.int = TRUE)

Régression ordinale

Pour un modèle ordinal, il existe une version simplifiée des modèles ordinaux directement disponible dans survey via la fonction svyolr.

rego <- svyolr(trav.satisf ~ sexe + etud + trav.imp, design = dw)
summary(rego)
Call:
svyolr(trav.satisf ~ sexe + etud + trav.imp, design = dw)

Coefficients:
                                    Value Std. Error
sexeHomme                   -0.1328026100  0.1545640
etudSecondaire              -0.0427151234  0.2751085
etudTechnique/Professionnel  0.0004261287  0.2492533
etudSupérieur                0.6424698737  0.2593446
etudmanquant                -0.4694599623  0.5033490
trav.impAussi                0.1207125976  0.5044264
trav.impMoins                0.0526740003  0.4895782
trav.impPeu                 -1.5303889517  0.7215699
                                 t value
sexeHomme                   -0.859207986
etudSecondaire              -0.155266460
etudTechnique/Professionnel  0.001709621
etudSupérieur                2.477282672
etudmanquant                -0.932672851
trav.impAussi                0.239306656
trav.impMoins                0.107590577
trav.impPeu                 -2.120915790

Intercepts:
                         Value   Std. Error t value
Insatisfaction|Equilibre -2.0392  0.5427    -3.7577
Equilibre|Satisfaction    0.2727  0.5306     0.5140
(952 observations deleted due to missingness)
confint(rego)
                                 2.5 %     97.5 %
sexeHomme                   -0.4357425  0.1701372
etudSecondaire              -0.5819179  0.4964876
etudTechnique/Professionnel -0.4881013  0.4889536
etudSupérieur                0.1341638  1.1507759
etudmanquant                -1.4560059  0.5170860
trav.impAussi               -0.8679450  1.1093702
trav.impMoins               -0.9068816  1.0122296
trav.impPeu                 -2.9446399 -0.1161380
Insatisfaction|Equilibre    -3.1027595 -0.9755811
Equilibre|Satisfaction       0.1607965  0.3846345

L’extension JLutils8 propose une méthode tidy pour les objets svyolr.

library(JLutils)
library(broom)
tidy(rego, exponentiate = TRUE, conf.int = TRUE)

Une alternative est d’avoir recours, comme pour la régression multinomiale, aux poids de réplication et à la fonction svyclm implémentée dans l’extension svrepmisc.

dwr <- as.svrepdesign(dw, type = "bootstrap", replicates = 100)
library(svrepmisc)
rego_alt <- svyclm(trav.satisf ~ sexe + etud + trav.imp, design = dwr)
Warning: (-1) Model failed to converge with max|grad| = 0.000467334 (tol = 1e-06) 
In addition: step factor reduced below minimum
Warning: (-1) Model failed to converge with max|grad| = 0.000195288 (tol = 1e-06) 
In addition: step factor reduced below minimum
Warning: (-1) Model failed to converge with max|grad| = 1.22232e-06 (tol = 1e-06) 
In addition: step factor reduced below minimum
Warning: (-1) Model failed to converge with max|grad| = 1.50607e-05 (tol = 1e-06) 
In addition: step factor reduced below minimum
rego_alt
                            Coefficient          SE t value
Insatisfaction|Equilibre    -2.03917466  0.59495641 -3.4274
Equilibre|Satisfaction       0.27271800  0.60404461  0.4515
sexeHomme                   -0.13280477  0.14292178 -0.9292
etudSecondaire              -0.04271403  0.29858905 -0.1431
etudTechnique/Professionnel  0.00042809  0.27576378  0.0016
etudSupérieur                0.64247607  0.26996537  2.3798
etudmanquant                -0.46945975  0.47155481 -0.9956
trav.impAussi                0.12071087  0.57405810  0.2103
trav.impMoins                0.05267146  0.54126096  0.0973
trav.impPeu                 -1.53039056  0.74088376 -2.0656
                             Pr(>|t|)    
Insatisfaction|Equilibre    0.0009206 ***
Equilibre|Satisfaction      0.6527250    
sexeHomme                   0.3552643    
etudSecondaire              0.8865682    
etudTechnique/Professionnel 0.9987648    
etudSupérieur               0.0194307 *  
etudmanquant                0.3221345    
trav.impAussi               0.8339273    
trav.impMoins               0.9226946    
trav.impPeu                 0.0417389 *  
---
Signif. codes:  
0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
confint(rego_alt)
                                 2.5 %      97.5 %
Insatisfaction|Equilibre    -3.2211594 -0.85718990
Equilibre|Satisfaction      -0.9273220  1.47275805
sexeHomme                   -0.4167438  0.15113429
etudSecondaire              -0.6359133  0.55048523
etudTechnique/Professionnel -0.5474248  0.54828096
etudSupérieur                0.1061427  1.17880940
etudmanquant                -1.4062857  0.46736618
trav.impAussi               -1.0197557  1.26117748
trav.impMoins               -1.0226379  1.12798083
trav.impPeu                 -3.0022855 -0.05849566
tidy(rego_alt, exponentiate = TRUE, conf.int = TRUE)

  1. Il existe également une fonction add.NA fournie avec R. Mais elle ne permet pas de choisir l’étiquette du nouveau niveau créé. Plus spécfiquement, cette étiquette est NA et non une valeur textuelle, ce qui peut créer des problèmes avec certaines fonctions.

  2. Pour plus de détails, voir http://www.spc.univ-lyon1.fr/polycop/odds%20ratio.htm.

  3. Cette extension est livrée avec de nombreuses vignettes dont une vignette d’introduction présentant le fonctionnement des différentes fonctions.

  4. Il existe également des méthodes de sélection ascendante pas à pas, mais nous les aborderons pas ici.

  5. Une alternative est d’avoir recours à l’extension mlogit que nous n’aborderons pas ici. Voir http://www.ats.ucla.edu/stat/r/dae/mlogit.htm (en anglais) pour plus de détails.

  6. Voir le chapitre dédié aux données pondérées.

  7. Compatibilité qui pourra éventuellement être introduite dans une future version de l’extension.

  8. devtools::install_github("larmarange/JLutils") pour l’installer

Analyse des correspondances multiples (ACM)

Il existe plusieurs techniques d’analyse factorielle dont les plus courantes sont l’analyse en composante principale (ACP) portant sur des variables quantitatives, l’analyse factorielle des correspondances (AFC) portant sur deux variables qualitatives et l’analyse des correspondances multiples (ACM) portant sur plusieurs variables qualitatives (il s’agit d’une extension de l’AFC). Pour combiner des variables à la fois quantitatives et qualitatives, on pourra avoir recours à l’analyse factorielle avec données mixtes.

Bien que ces techniques soient disponibles dans les extensions standards de R, il est souvent préférable d’avoir recours à deux autres extensions plus complètes, ade4 et FactoMineR, chacune ayant ses avantages et des possibilités différentes. Voici les fonctions les plus fréquentes :

Analyse Variables Fonction standard Fonction ade4 Fonctions FactoMineR
ACP plusieurs variables quantitatives princomp dudi.pca PCA
AFC deux variables qualitatives corresp dudi.coa CA
ACM plusieurs variables qualitatives mca dudi.acm MCA
Analyse mixte plusieurs variables quantitatives et/ou qualitatives FAMD dudi.mix

Dans la suite de ce chapitre, nous n’arboderons que l’analyse des correspondances multiples (ACM).

On trouvera également de nombreux supports de cours en français sur l’analyse factorielle sur le site de François Gilles Carpentier : http://geai.univ-brest.fr/~carpenti/.

Principe général

L’analyse des correspondances multiples est une technique descriptive visant à résumer l’information contenu dans un grand nombre de variables afin de faciliter l’interprétention des corrélations existantes entre ces différentes variables. On cherche à savoir quelles sont les modalités corrélées entre elles.

L’idée générale est la suivante1. L’ensemble des individus peut être représenté dans un espace à plusieurs dimensions où chaque axe représente les différentes variables utilisées pour décrire chaque individu. Plus précisément, pour chaque variable qualitative, il y a autant d’axes que de modalités moins un. Ainsi il faut trois axes pour décrire une variable à quatre modalités. Un tel nuage de points est aussi difficile à interpréter que de lire directement le fichier de données. On ne voit pas les corrélations qu’il peut y avoir entre modalités, par exemple qu’aller au cinéma est plus fréquent chez les personnes habitant en milieu urbain. Afin de mieux représenter ce nuage de points, on va procéder à un changement de systèmes de coordonnées. Les individus seront dès lors projetés et représentés sur un nouveau système d’axe. Ce nouveau système d’axes est choisis de telle manière que la majorité des variations soit concentrées sur les premiers axes. Les deux-trois premiers axes permettront d’expliquer la majorité des différences observées dans l’échantillon, les autres axes n’apportant qu’une faible part additionnelle d’information. Dès lors, l’analyse pourra se concentrer sur ses premiers axes qui constitueront un bon résumé des variations observables dans l’échantillon.

Avant toute ACM, il est indispensable de réaliser une analyse préliminaire de chaque variable, afin de voir si toutes les classes sont aussi bien représentées ou s’il existe un déséquilibre. L’ACM est sensible aux effectifs faibles, aussi il est préférable de regrouper les classes peu représentées le cas échéant.

ACM avec ade4

Si l’extension ade4 n’est pas présente sur votre PC, il vous faut l’installer :

install.packages("ade4", dep = TRUE)

Dans tous les cas, il faut penser à la charger en mémoire :

library(ade4)

Comme précédemment, nous utiliserons le fichier de données hdv2003 fourni avec l’extension questionr.

library(questionr)
data(hdv2003)
d <- hdv2003

En premier lieu, comme dans le chapitre sur la régression logistique, nous allons créer une variable groupe d’âges et regrouper les modalités de la variable « niveau d’étude ».

d$grpage <- cut(d$age, c(16, 25, 45, 65, 93), right = FALSE, include.lowest = TRUE)
d$etud <- d$nivetud
levels(d$etud) <- c(
  "Primaire", "Primaire", "Primaire", "Secondaire", "Secondaire",
  "Technique/Professionnel", "Technique/Professionnel", "Supérieur"
)

Ensuite, nous allons créer un tableau de données ne contenant que les variables que nous souhaitons prendre en compte pour notre analyse factorielle.

d2 <- d[, c("grpage", "sexe", "etud", "peche.chasse", "cinema", "cuisine", "bricol", "sport", "lecture.bd")]

Le calcul de l’ACM se fait tout simplement avec la fonction dudi.acm.

acm <- dudi.acm(d2)

Par défaut, la fonction affichera le graphique des valeurs propres de chaque axe (nous y reviendrons) et vous demandera le nombre d’axes que vous souhaitez conserver dans les résultats. Le plus souvent, cinq axes seront largement plus que suffisants. Vous pouvez également éviter cette étape en indiquant directement à dudi.acm de vous renvoyer les cinq premiers axes ainsi :

acm <- dudi.acm(d2, scannf = FALSE, nf = 5)

Le graphique des valeurs propres peut être reproduit avec screeplot :

screeplot(acm)
Valeurs propres ou inerties de chaque axe

Les mêmes valeurs pour les premiers axes s’obtiennent également avec summary2 :

summary(acm)
Class: acm dudi
Call: dudi.acm(df = d2, scannf = FALSE, nf = 5)

Total inertia: 1.451

Eigenvalues:
    Ax1     Ax2     Ax3     Ax4     Ax5 
 0.2474  0.1672  0.1309  0.1263  0.1176 

Projected inertia (%):
    Ax1     Ax2     Ax3     Ax4     Ax5 
 17.055  11.525   9.022   8.705   8.109 

Cumulative projected inertia (%):
    Ax1   Ax1:2   Ax1:3   Ax1:4   Ax1:5 
  17.06   28.58   37.60   46.31   54.42 

(Only 5 dimensions (out of 15) are shown)

L’inertie totale est de 1,451 et l’axe 1 en explique 0,1474 soit 17 %. L’inertie projetée cumulée nous indique que les deux premiers axes expliquent à eux seuls 29 % des variations observées dans notre échantillon.

Pour comprendre la signification des différents axes, il importe d’identifier quelles sont les variables/ modalités qui contribuent le plus à chaque axe. Une première représentation graphique est le cercle de corrélation des modalités. Pour cela, on aura recours à s.corcicle. On indiquera d’abord acm$co si l’on souhaite représenter les modalités ou acm$li si l’on souhaite représenter les individus. Les deux chiffres suivant indiquent les deux axes que l’on souhaite afficher (dans le cas présent les deux premiers axes). Enfin, le paramètre clabel permet de modifier la taille des étiquettes.

s.corcircle(acm$co, 1, 2, clabel = 0.7)
Cercle de corrélations des modalités sur les deux premiers axes

On pourra avoir également recours à boxplot pour visualiser comment se répartissent les modalités de chaque variable sur un axe donné3.

boxplot(acm)
Répartition des modalités selon le premier axe
boxplot(acm, 2)
Répartition des modalités selon le second axe

Le tableau acm$cr contient les rapports de corrélation (variant de 0 à 1) entre les variables et les axes choisis au départ de l’ACM. Pour représenter graphiquement ces rapports, utiliser la fonction barplot ainsi : barplot(acm$cr[,num],names.arg=row.names( acm$cr),las=2)num est le numéro de l’axe à représenter. Pour l’interprétation des axes, se concentrer sur les variables les plus structurantes, c’est-à-dire dont le rapport de corrélation est le plus proche de 1.

par(mfrow = c(2, 2))
for (i in 1:4) barplot(acm$cr[, i], names.arg = row.names(acm$cr), las = 2, main = paste("Axe", i))

par(mfrow = c(1, 1))
Rapports de corrélation des variables sur les 4 premiers axes

Le paramètre mfrow de la fonction par permet d’indiquer à R que l’on souhaite afficher plusieurs graphiques sur une seule et même fenêtre, plus précisément que l’on souhaite diviser la fenêtre en deux lignes et deux colonnes.

Dans l’exemple précédent, après avoir produit notre graphique, nous avons réinitilisé cette valeur à c(1, 1) (un seul graphique par fenêtre) pour ne pas affecter les prochains graphiques que nous allons produire.

Pour représenter, les modalités dans le plan factoriel, on utilisera la fonction s.label. Par défaut, les deux premiers axes sont représentés.

s.label(acm$co, clabel = 0.7)
Répartition des modalités selon les deux premiers axes

Il est bien sur possible de préciser les axes à représenter. L’argument boxes permet quant à lui d’indiquer si l’on souhaite tracer une boîte pour chaque modalité.

s.label(acm$co, 3, 4, clabel = 0.7, boxes = FALSE)
Répartition des modalités selon les axes 3 et 4

Bien entendu, on peut également représenter les individus. En indiquant clabel=0 (une taille nulle pour les étiquettes), s.label remplace chaque observation par un symbole qui peut être spécifié avec pch.

s.label(acm$li, clabel = 0, pch = 17)
Répartition des individus selon les deux premiers axes

L’agument pch permet de spécifier le symbole à utiliser. Il peut prendre soit un nombre entier compris entre 0 et 25, soit un charactère textuel.

Lorsque l’on réalise une ACM, il n’est pas rare que plusieurs observations soient identiques, c’est-à-dire correspondent à la même combinaison de modalités. Dès lors, ces observations seront projetées sur le même point dans le plan factoriel. Une représentation classique des observations avec s.label ne permettra pas de rendre compte les effectifs de chaque point.

Le package JLutils, disponible seulement sur GitHub, propose une fonction s.freq représentant chaque point par un carré proportionnel au nombre d’individus.

Pour installer JLutils, on aura recours au package devtools et à sa fonction install_github :

library(devtools)
install_github("larmarange/JLutils")

La fonction s.freq s’emploie de manière similaire aux autres fonctions graphiques de ade4. Le paramètre csize permet d’ajuster la taille des carrés.

library(JLutils)
s.freq(acm$li)

L’interprétation est tout autre, non ?

Gaston Sanchez propose un graphique amélioré des modalités dans le plan factoriel à cette adresse : http://rpubs.com/gaston/MCA.

La fonction s.value permet notamment de représenter un troisième axe factoriel. Dans l’exemple ci-après, nous projettons les individus selon les deux premiers axes factoriels. La taille et la couleur des carrés dépendent pour leur part de la coordonnée des individus sur le troisième axe factoriel. Le paramètre csi permet d’ajuster la taille des carrés.

s.value(acm$li, acm$li[, 3], 1, 2, csi = 0.5)
Répartition des individus selon les trois premiers axes

s.arrow permet de représenter les vecteurs variables ou les vecteurs individus sous la forme d’une flèche allant de l’origine du plan factoriel aux coordonnées des variables/individus :

s.arrow(acm$co, clabel = 0.7)
Vecteurs des modalités selon les deux premiers axes

s.hist permet de représenter des individus (ou des modalités) sur le plan factoriel et d’afficher leur distribution sur chaque axe :

s.hist(acm$li, clabel = 0, pch = 15)
Distribution des individus dans le plan factoriel

s.class et s.chull permettent de représenter les différentes observations classées en plusieurs catégories. Cela permet notamment de projeter certaines variables.

s.class représente les observations par des points, lie chaque observation au barycentre de la modalité à laquelle elle appartient et dessine une ellipse représentant la forme générale du nuage de points :

library(RColorBrewer)
s.class(acm$li, d2$sexe, col = brewer.pal(4, "Set1"))
Individus dans le plan factoriel selon le sexe (s.class)

s.chull représente les barycentres de chaque catégorie et dessine des lignes de niveaux représentant la distribution des individus de cette catégorie. Les individus ne sont pas directement représentés :

s.chull(acm$li, d2$sexe, col = brewer.pal(4, "Set1"))
Individus dans le plan factoriel selon le sexe (s.chull)

Il est préférable de fournir une liste de couleurs (via le paramètre col) pour rendre le graphique plus lisible. Si vous avez installé l’extension RColorBrewer, vous pouvez utiliser les différentes palettes de couleurs proposées. Pour afficher les palettes disponibles, utilisez display.brewer.all.

library(RColorBrewer)
display.brewer.all(8)

Pour obtenir une palette de couleurs, utilisez la fonction brewer.pal avec les arguments n (nombre de couleurs demandées) et pal(nom de la palette de couleurs désirée).

Pour plus d’informations sur les palettes Color Brewer, voir http://colorbrewer2.org/.

La variable catégorielle transmise à s.class ou s.chull n’est pas obligatoirement une des variables retenues pour l’ACM. Il est tout à fait possible d’utiliser une autre variable. Par exemple :

s.class(acm$li, d$trav.imp, col = brewer.pal(4, "Set1"))
Individus dans le plan factoriel selon l’importance donnée au travail

Les fonctions scatter et biplot sont équivalentes : elles appliquent s.class à chaque variable utilisée pour l’ACM.

scatter(acm, col = brewer.pal(4, "Set1"))
La fonction scatter appliquée au résultat d’une ACM

L’extension explor écrite par Julien Barnier offre une interface graphique interactive permettant d’explorer les résultats d’une analyse factorielle. Essayons donc la fonction explor. C’est magique !

library(explor)
explor(acm)

ACM avec FactoMineR

Comme avec ade4, il est nécessaire de préparer les données au préalable (voir section précédente).

L’ACM se calcule avec la fonction MCA, l’argument ncp permettant de choisir le nombre d’axes à retenir :

library(FactoMineR)
acm2 <- MCA(d2, ncp = 5, graph = FALSE)
acm2
**Results of the Multiple Correspondence Analysis (MCA)**
The analysis was performed on 2000 individuals, described by 9 variables
*The results are available in the following objects:

   name              description                       
1  "$eig"            "eigenvalues"                     
2  "$var"            "results for the variables"       
3  "$var$coord"      "coord. of the categories"        
4  "$var$cos2"       "cos2 for the categories"         
5  "$var$contrib"    "contributions of the categories" 
6  "$var$v.test"     "v-test for the categories"       
7  "$ind"            "results for the individuals"     
8  "$ind$coord"      "coord. for the individuals"      
9  "$ind$cos2"       "cos2 for the individuals"        
10 "$ind$contrib"    "contributions of the individuals"
11 "$call"           "intermediate results"            
12 "$call$marge.col" "weights of columns"              
13 "$call$marge.li"  "weights of rows"                 
acm2$eig
       eigenvalue percentage of variance
dim 1  0.25757489              15.454493
dim 2  0.18363502              11.018101
dim 3  0.16164626               9.698776
dim 4  0.12871623               7.722974
dim 5  0.12135737               7.281442
dim 6  0.11213331               6.727999
dim 7  0.10959377               6.575626
dim 8  0.10340564               6.204338
dim 9  0.09867478               5.920487
dim 10 0.09192693               5.515616
dim 11 0.07501208               4.500725
dim 12 0.06679676               4.007805
dim 13 0.06002063               3.601238
dim 14 0.05832024               3.499215
dim 15 0.03785276               2.271166
       cumulative percentage of variance
dim 1                           15.45449
dim 2                           26.47259
dim 3                           36.17137
dim 4                           43.89434
dim 5                           51.17579
dim 6                           57.90378
dim 7                           64.47941
dim 8                           70.68375
dim 9                           76.60424
dim 10                          82.11985
dim 11                          86.62058
dim 12                          90.62838
dim 13                          94.22962
dim 14                          97.72883
dim 15                         100.00000
sum(acm2$eig[, 1])
[1] 1.666667

En premier lieu, il apparait que l’inertie totale obtenue avec MCA est différente de celle observée avec dudi.acm. Cela est dû à un traitement différents des valeurs manquantes. Alors que dudi.acm exclu les valeurs manquantes, MCA les considèrent, par défaut, comme une modalité additionnelle. Pour calculer l’ACM uniquement sur les individus n’ayant pas de valeur manquante, on aura recours à complete.cases :

acm2 <- MCA(d2[complete.cases(d2), ], ncp = 5, graph = FALSE)
acm2$eig
       eigenvalue percentage of variance
dim 1  0.24790700              17.162792
dim 2  0.16758465              11.602014
dim 3  0.13042357               9.029324
dim 4  0.12595105               8.719688
dim 5  0.11338629               7.849820
dim 6  0.10976674               7.599236
dim 7  0.10060204               6.964757
dim 8  0.09802387               6.786268
dim 9  0.09283131               6.426783
dim 10 0.07673502               5.312425
dim 11 0.06609694               4.575942
dim 12 0.05950655               4.119684
dim 13 0.05562942               3.851267
       cumulative percentage of variance
dim 1                           17.16279
dim 2                           28.76481
dim 3                           37.79413
dim 4                           46.51382
dim 5                           54.36364
dim 6                           61.96287
dim 7                           68.92763
dim 8                           75.71390
dim 9                           82.14068
dim 10                          87.45311
dim 11                          92.02905
dim 12                          96.14873
dim 13                         100.00000
sum(acm2$eig[, 1])
[1] 1.444444

Les possibilités graphiques de FactoMineR sont différentes de celles de ade4. Un recours à la fonction plot affichera par défaut les individus, les modalités et les variables. La commande ?plot.MCA permet d’accéder au fichier d’aide de cette fonction (i.e. de la méthode générique plot appliquée aux objets de type MCA) et de voir toutes les options graphiques. L’argument choix permet de spécifier ce que l’on souhaite afficher (« ind » pour les individus et les catégories, « var » pour les variables). L’argument invisible quant à lui permet de spécifier ce que l’on souhaite masquer. Les axes à afficher se précisent avec axes. Voir les exemples ci-dessous.

plot(acm2)
Plan factoriel (deux premiers axes)
plot(acm2, axes = c(3, 4))
Plan factoriel (axes 3 et 4)
plot(acm2, choix = "ind")
Plan factoriel (seulement les individus et les catégories)
plot(acm2, choix = "ind", invisible = "ind")
Plan factoriel (seulement les catégories)
plot(acm2, choix = "var")
Plan factoriel (seulement les variables)

La fonction plotellipses trace des ellipses de confiance atour des modalités de variables qualitatives. L’objectif est de voir si les modalités d’une variable qualitative sont significativement différentes les unes des autres.

Par défaut (means=TRUE), les ellipses de confiance sont calculées pour les coordonnées moyennes de chaque catégorie.

plotellipses(acm2)
Ellipses de confiance (means=TRUE) dans le plan factoriel

L’option means=FALSE calculera les ellipses de confiance pour l’ensemble des coordonnées des observations relevant de chaque catégorie.

plotellipses(acm2, means = FALSE)
Ellipses de confiance (means=FALSE) dans le plan factoriel

La fonction dimdesc aide à décrire et interpréter les dimensions de l’ACM. Cette fonction est très utile quand le nombre de variables est élevé. Elle permet de voir à quelles variables les axes sont le plus liés : quelles variables et quelles modalités décrivent le mieux chaque axe ?

Pour les variables qualitatives, un modèle d’analyse de variance à un facteur est réalisé pour chaque dimension ; les variables à expliquer sont les coordonnées des individus et la variable explicative est une des variables qualitatives. Un test F permet de voir si la variable a un effet significatif sur la dimension et des tests T sont réalisés modalité par modalité (avec le contraste somme des alpha_i=0). Cela montre si les coordonnées des individus de la sous-population définie par une modalité sont significativement différentes de celles de l’ensemble de la population (i.e. différentes de 0). Les variables et modalités sont triées par probabilité critique et seules celles qui sont significatives sont gardées dans le résultat.

dd <- dimdesc(acm2, axes = 1:2)
dd$`Dim 1`

Extensions complémentaires

factoextra

L’extension factoextra fournit des fonctions graphiques ggplot2 pour visualiser les résultats d’une analyse factorielle, réalisée avec ade4 ou FactoMineR.

Plus d’informations sur https://rpkgs.datanovia.com/factoextra/.

explor

L’extension explor fournit une interface graphique pour explorer les résultats d’une analyse factorielle, réalisée avec ade4 ou FactoMineR.

Interface graphique de explor

Plus d’informations sur https://github.com/juba/explor/.

Factoshiny

L’extension Factoshiny permet d’améliorer facilement et de façon interactive les graphiques produits par FactoMineR pour les rendre beaucoup plus lisibles.

Plus d’informations sur http://factominer.free.fr/graphs/factoshiny-fr.html.

FactoInvestigate

L’extension FactoInvestigate décrit et interprète automatiquement les résultats de votre analyse factorielle (ACP, AFC ou ACM) en choisissant les graphes les plus appropriés pour un rapport.

Vous avez juste à faire l’analyse comme habituellement avec FactoMineR ou Factoshiny, et ensuite utiliser FactoInvestigate pour obtenir un rapport automatisé.

Plus d’informations sur http://factominer.free.fr/reporting/index_fr.html.

Voir aussi

Un tutoriel détaillé en français, Visualiser une analyse géométrique des données avec ggplot2 (R/RStudio), est disponible sur le blog Quanti : https://quanti.hypotheses.org/1871.


  1. Pour une présentation plus détaillée, voir
    http://www.math.univ-toulouse.fr/~baccini/zpedago/asdm.pdf.

  2. On pourra également avoir recours à la fonction inertia.dudi pour l’ensemble des axes.

  3. La fonction score constituera également une aide à l’interprétation des axes.

Classification ascendante hiérarchique (CAH)

Il existe de nombreuses techniques statistiques visant à partinionner une population en différentes classes ou sous-groupes. La classification ascendante hiérarchique (CAH) est l’une d’entre elles. On cherche à ce que les individus regroupés au sein d’une même classe (homogénéité intra-classe) soient le plus semblables possibles tandis que les classes soient le plus dissemblables (hétérogénéité inter-classe).

Le principe de la CAH est de rassembler des individus selon un critère de ressemblance défini au préalable qui s’exprimera sous la forme d’une matrice de distances, exprimant la distance existant entre chaque individu pris deux à deux. Deux observations identiques auront une distance nulle. Plus les deux observations seront dissemblables, plus la distance sera importante. La CAH va ensuite rassembler les individus de manière itérative afin de produire un dendrogramme ou arbre de classification. La classification est ascendante car elle part des observations individuelles ; elle est hiérarchique car elle produit des classes ou groupes de plus en plus vastes, incluant des sous-groupes en leur sein. En découpant cet arbre à une certaine hauteur choisie, on produira la partition désirée.

On trouvera également de nombreux supports de cours en français sur la CAH sur le site de François Gilles Carpentier : http://pagesperso.univ-brest.fr/~carpenti/.

Calculer une matrice des distances

La notion de ressemblance entre observations est évaluée par une distance entre individus. Plusieurs type de ditances existent selon les données utilisées.

Il existe de nombreuses distances mathématiques pour les variables quantitatives (euclidiennes, Manhattan…) que nous n’aborderons pas ici1. La plupart peuvent être calculées avec la fonction dist.

Usuellement, pour un ensemble de variables qualitatives, on aura recours à la distance du F² qui est celle utilisée pour l’analyse des correspondances multiples (voir le chapitre dédié). Avec l’extension ade4, la distance du F² s’obtient avec la fonction dist.dudi2. Le cas particulier de la CAH avec l’extension FactoMineR sera abordée dans une section spécifique ci-après. Nous évoquerons également la distance de Gower qui peut s’appliquer à un ensemble de variables à la fois qualitatives et quantitatives et qui se calcule avec la fonction daisy de l’extension cluster. Enfin, dans le chapitre sur l’analyse de séquences, nous verrons également la fonction seqdist (extension TraMineR) permettant de calculer une distance entre séquences.

Distance de Gower

En 1971, Gower a proposé un indice de similarité qui porte son nom3. L’objectif de cet indice consiste à mesurer dans quelle mesure deux individus sont semblables. L’indice de Gower varie entre 0 et 1. Si l’indice vaut 1, les deux individus sont identiques. À l’opposé, s’il vaut 0, les deux individus considérés n’ont pas de point commun. Si l’on note Sg l’indice de similarité de Gower, la distance de Gower Dg s’obtient simplement de la manière suivante : Dg = 1 - Sg. Ainsi, la distance sera nulle entre deux individus identiques et elle sera égale à 1 entre deux individus totalement différents. Cette distance s’obtient sous R avec la fonction daisy du package cluster.

L’indice de similarité de Gower entre deux individus x1 et x2 se calcule de la manière suivante :

Sgx1x2=1pj=1ps12j

p représente le nombre total de caractères (ou de variables) descriptifs utilisés pour comparer les deux individus4. s12j représente la similarité partielle entre les individus 1 et 2 concernant le descripteur j. Cette similarité partielle se calcule différemment s’il s’agit d’une variable qualitative ou quantitative :

  • variable qualitative : s12j vaut 1 si la variable j prend la même valeur pour les individus 1 et 2, et vaut 0 sinon. Par exemple, si 1 et 2 sont tous les deux « grand », alors s12j vaudra 1. Si 1 est « grand » et 2 « petit », s12j vaudra 0.
  • variable quantitative : la différence absolue entre les valeurs des deux variables est tout d’abord calculée, soit |y1j - y2j|. Puis l’écart maximum observé sur l’ensemble du fichier est déterminé et noté Rj. Dès lors, la similarité partielle vaut S12j = 1 - |y1j - y2j| / Rj.

Dans le cas où l’on n’a que des variables qualitatives, la valeur de l’indice de Gower correspond à la proportion de caractères en commun. Supposons des individus 1 et 2 décris ainsi :

  1. homme / grand / blond / étudiant / urbain
  2. femme / grande / brune / étudiante / rurale

Sur les 5 variables utilisées pour les décrire, 1 et 2 ont deux caractéristiques communes : ils sont grand(e)s et étudiant(e)s. Dès lors, l’indice de similarité de Gower entre 1 et 2 vaut 2/5 = 0,4 (soit une distance de 1 - 0,4 = 0,6).

Plusieurs approches peuvent être retenues pour traiter les valeurs manquantes :

  • supprimer tout individu n’étant pas renseigné pour toutes les variables de l’analyse ;
  • considérer les valeurs manquantes comme une modalité en tant que telle ;
  • garder les valeurs manquantes en tant que valeurs manquantes.

Le choix retenu modifiera les distances de Gower calculées. Supposons que l’on ait :

  1. homme / grand / blond / étudiant / urbain
  2. femme / grande / brune / étudiante / manquant

Si l’on supprime les individus ayant des valeurs manquantes, 2 est retirée du fichier d’observations et aucune distance n’est calculée.

Si l’on traite les valeurs manquantes comme une modalité particulière, 1 et 2 partagent alors 2 caractères sur les 5 analysés, la distance de Gower entre eux est alors de 1 - 2/5 =1 - 0,4 = 0,6.

Si on garde les valeurs manquantes, l’indice de Gower est dès lors calculé sur les seuls descripteurs renseignés à la fois pour 1 et 2. La distance de Gower sera calculée dans le cas présent uniquement sur les 4 caractères renseignés et vaudra 1 - 2/4 = 0,5.

Distance du F²

Il s’agit de la distance utilisée dans les analyses de correspondance multiples (ACM). C’est une variante de la distance du ². Nous considérons ici que nous avons Q questions (soit Q variables initiales de type facteur). À chaque individu est associé un patron c’est-à-dire une certaine combinaison de réponses aux Q questions. La distance entre deux individus correspond à la distance entre leurs deux patrons. Si les deux individus présentent le même patron, leur distance sera nulle. La distance du F² peut s’exprimer ainsi :

dF22LiLj=1Qkdik-djk2fk

Li et Lj sont deux patrons, Q le nombre total de questions. dik vaut 1 si la modalité k est présente dans le patron Li, 0 sinon. fk est la fréquence de la modalité k dans l’ensemble de la population.

Exprimé plus simplement, on fait la somme de l’inverse des modalités non communes aux deux patrons, puis on divise par le nombre total de question. Si nous reprenons notre exemple précédent :

  1. homme / grand / blond / étudiant / urbain
  2. femme / grande / brune / étudiante / rurale

Pour calculer la distance entre 1 et 2, il nous faut connaître la proportion des différentes modalités dans l’ensemble de la population étudiée. En l’occurrence :

  • hommes : 52 % / femmes : 48 %
  • grand : 30 % / moyen : 45 % / petit : 25 %
  • blond : 15 % / châtain : 45 % / brun : 30 % / blanc : 10 %
  • étudiant : 20 % / salariés : 65 % / retraités : 15 %
  • urbain : 80 % / rural : 20 %

Les modalités non communes entre les profils de 1 et 2 sont : homme, femme, blond, brun, urbain et rural. La distance du F² entre 1 et 2 est donc la suivante :

dF22L1L2=1510,52+10,48+10,15+10,30+10,80+10,20=4,05

Cette distance, bien que moins intuitive que la distance de Gower évoquée précédemment, est la plus employée pour l’analyse d’enquêtes en sciences sociales. Il faut retenir que la distance entre deux profils est dépendante de la distribution globale de chaque modalité dans la population étudiée. Ainsi, si l’on recalcule les distances entre individus à partir d’un sous-échantillon, le résultat obtenu sera différent. De manière générale, les individus présentant des caractéristiques rares dans la population vont se retrouver éloignés des individus présentant des caractéristiques fortement représentées.

Exemple

Nous allons reprendre l’ACM calculée avec dudi.acm (ade4) dans le chapitre consacré à l’ACM :

library(questionr)
data(hdv2003)
d <- hdv2003
d$grpage <- cut(d$age, c(16, 25, 45, 65, 93), right = FALSE, include.lowest = TRUE)
d$etud <- d$nivetud
levels(d$etud) <- c(
  "Primaire", "Primaire", "Primaire", "Secondaire", "Secondaire",
  "Technique/Professionnel", "Technique/Professionnel", "Supérieur"
)
d2 <- d[, c("grpage", "sexe", "etud", "peche.chasse", "cinema", "cuisine", "bricol", "sport", "lecture.bd")]
library(ade4)
acm <- dudi.acm(d2, scannf = FALSE, nf = 5)

La matrice des distances s’obtient dès lors avec la fonction dist.dudi :

md <- dist.dudi(acm)

Calcul du dendrogramme

Il faut ensuite choisir une méthode d’agrégation pour construire le dendrogramme. De nombreuses solutions existent (saut minimum, distance maximum, moyenne, Ward…). Chacune d’elle produira un dendrogramme différent. Nous ne détaillerons pas ici ces différentes techniques5. Cependant, à l’usage, on privilégiera le plus souvent la méthode de Ward6. De manière simplifiée, cette méthode cherche à minimiser l’inertie intra-classe et à maximiser l’inertie inter-classe afin d’obtenir des classes les plus homogènes possibles. Cette méthode est souvent incorrectement présentée comme une méthode de minimisation de la variance alors qu’au sens strict Ward vise l’augmentation mininum de la somme des carrés (“minimum increase of sum-of-squares (of errors)”)7.

En raison de la variété des distances possibles et de la variété des techniques d’agrégation, on pourra être amené à réaliser plusieurs dendrogrammes différents sur un même jeu de données jusqu’à obtenir une classification qui fait « sens ».

La fonction de base pour le calcul d’un dendrogramme est hclust en précisant le critère d’agrégation avec method. Dans notre cas, nous allons opter pour la méthode de Ward appliquée au carré des distances (ce qu’on indique avec method = "ward.D2"8) :

arbre <- hclust(md, method = "ward.D2")

Le temps de calcul d’un dendrogramme peut être particulièrement important sur un gros fichier de données. L’extension fastcluster permet de réduire significativement le temps de calcul. Il suffit d’installer puis d’appeler cette extension. La fonction hclust sera automatiquement remplacée par cette version optimisée. Elle prends les mêmes paramètres :

library(fastcluster)
arbre <- hclust(md, method = "ward.D2")

Le dendrogramme obtenu peut être affiché simplement avec plot. Lorsque le nombre d’individus est important, il peut être utile de ne pas afficher les étiquettes des individus avec labels=FALSE.

plot(arbre, labels = FALSE, main = "Dendrogramme")
Dendrogramme obtenu avec hclust

La fonction agnes de l’extension cluster peut également être utilisée pour calculer le dendrogramme. Cependant, à l’usage, elle semble être un peu plus lente que hclust.

library(cluster)
arbre2 <- agnes(md, method = "ward")

ATTENTION : la méthode implémentée dans la fonction agnes correspond à l’option method = "ward.D2" de hclust.

Le résultat obtenu n’est pas au même format que celui de hclust. Il est possible de transformer un objet agnes au format hclust avec as.hclust.

as.hclust(arbre2)

Découper le dendrogramme

Pour obtenir une partition de la population, il suffit de découper le dendrogramme obtenu à une certaine hauteur. En premier lieu, une analyse de la forme du dendrogramme pourra nous donner une indication sur le nombre de classes à retenir. Dans notre exemple, deux branches bien distinctes apparaissent sur l’arbre.

Pour nous aider, nous pouvons représenter les sauts d’inertie du dendrogramme selon le nombre de classes retenues.

inertie <- sort(arbre$height, decreasing = TRUE)
plot(inertie[1:20], type = "s", xlab = "Nombre de classes", ylab = "Inertie")
Inertie du dendrogramme

On voit trois sauts assez nets à 2, 5 et 8 classes, que nous avons représentés ci-dessous respectivement en vert, en rouge et en bleu.

plot(inertie[1:20], type = "s", xlab = "Nombre de classes", ylab = "Inertie")
points(c(2, 5, 8), inertie[c(2, 5, 8)], col = c("green3", "red3", "blue3"), cex = 2, lwd = 3)
Sauts d’inertie du dendrogramme

La fonction rect.hclust permet de visualiser les différentes partitions directement sur le dendrogramme.

plot(arbre, labels = FALSE, main = "Partition en 2, 5 ou 8 classes", xlab = "", ylab = "", sub = "", axes = FALSE, hang = -1)
rect.hclust(arbre, 2, border = "green3")
rect.hclust(arbre, 5, border = "red3")
rect.hclust(arbre, 8, border = "blue3")
Différentes partitions du dendrogramme

L’extension FactoMineR (que nous aborderons dans une section dédiée ci-après) suggère d’utiliser la partition ayant la plus grande perte relative d’inertie.

L’extension JLutils (disponible sur GitHub) propose une fonction best.cutree qui permet de calculer cette indicateur à partir de n’importe quel dendrogramme calculé avec hclust ou agnes.

Pour installer JLutils, on aura recours au package devtools et à sa fonction install_github :

library(devtools)
install_github("larmarange/JLutils")

Par défaut, best.cutree regarde quelle serait la meilleure partition entre 3 et 20 classes.

library(JLutils)
best.cutree(arbre)
[1] 5

En l’occurence il s’agirait d’une partition en 5 classes. Il est possible de modifier le minimum et le maximum des partitions recherchées avec min et max.

best.cutree(arbre, min = 2)
[1] 2

On peut également représenter le graphique des pertes relatives d’inertie avec graph=TRUE. La meilleure partition selon ce critère est représentée par un point noir et la seconde par un point gris.

best.cutree(arbre, min = 2, graph = TRUE, xlab = "Nombre de classes", ylab = "Inertie relative")

[1] 2
Perte relative d’inertie selon le nombre de classes

Un découpage en deux classes minimise ce critère. Cependant, si l’on souhaite réaliser une analyse un peu plus fine, un nombre de classes plus élevé serait pertinent. Nous allons donc retenir un découpage en cinq classes. Le découpage s’effectue avec la fonction cutree.

typo <- cutree(arbre, 5)
freq(typo)

Il existe de multiples autres indicateurs statistiques cherchant à mesurer la qualité de chaque partition. Pour cela, on pourra par exemple avoir recours à la fonction as.clustrange de l’extension WeightedCluster.

Pour plus d’informations, voir le manuel de la librairie WeightedCluster, chapitre 7.

La typologie obtenue peut être représentée dans le plan factoriel avec s.class.

par(mfrow = c(1, 2))
library(RColorBrewer)
s.class(acm$li, as.factor(typo), col = brewer.pal(5, "Set1"), sub = "Axes 1 et 2")
s.class(acm$li, as.factor(typo), 3, 4, col = brewer.pal(5, "Set1"), sub = "Axes 3 et 4")

par(mfrow = c(1, 1))
Projection de la typologie obtenue par CAH selon les 4 premiers axes

De nombreuses possibilités graphiques sont possibles avec les dendrogrammes. Des exemples documentés sont disponibles à cette adresse : http://rpubs.com/gaston/dendrograms.

Romain François a developpé une fonction A2Rplot permettant de réaliser facilement un dendrogramme avec les branches colorées9. Par commodité, cette fonction est disponible directement au sein de l’extension JLutils.

Pour réaliser le graphique, on indiquera le nombre de classes et les couleurs à utiliser pour chaque branche de l’arbre :

A2Rplot(arbre, k = 5, boxes = FALSE, col.up = "gray50", col.down = brewer.pal(5, "Dark2"), show.labels = FALSE)

On pourra aussi noter l’extension ggdendro pour représenter des dendrogrammes avec ggplot2 ou encore l’extension dendextend qui permet de manipuler, représenter et comparer des dendrogrammes10.

CAH avec l’extension FactoMineR

L’extension FactoMineR fournit une fonction HCPC permettant de réaliser une classification hiérarchique à partir du résultats d’une analyse factorielle réalisée avec la même extension (voir la section dédiée du chapitre sur l’ACM).

HCPC réalise à la fois le calcul de la matrice des distances, du dendrogramme et le partitionnement de la population en classes. Par défaut, HCPC calcule le dendrogramme à partir du carré des distances du F² et avec la méthode de Ward.

Par défaut, l’arbre est affiché à l’écran et l’arbre sera coupé selon la partition ayant la plus grande perte relative d’inertie (comme avec best.cutree). Utilisez graph=FALSE pour ne pas afficher le graphique et l’argument nb.clust pour indiquer le nombre de classes désirées.

library(FactoMineR)
acm2 <- MCA(d2[complete.cases(d2), ], ncp = 5, graph = FALSE)
cah <- HCPC(acm2, graph = FALSE)

On pourra représenter le dendrogramme avec plot et l’argument choice="tree".

plot(cah, choice = "tree")
Dendrogramme obtenu avec HCPC (5 axes)

Il apparait que le dendrogramme obtenu avec HCPC diffère de celui que nous avons calculé précédemment en utilisant la matrice des distances fournies par dist.dudi. Cela est dû au fait que HCPC procède différement pour calculer la matrice des distances en ne prenant en compte que les axes retenus dans le cadre de l’ACM. Pour rappel, nous avions retenu que 5 axes dans le cadre de notre ACM :

acm2 <- MCA(d2[complete.cases(d2), ], ncp = 5, graph = FALSE)

HCPC n’a donc pris en compte que ces 5 premiers axes pour calculer les distances entre les individus, considérant que les autres axes n’apportent que du « bruit » rendant la classification instable. Cependant, comme le montre summary(acm2), nos cinq premiers axes n’expliquent que 54 % de la variance. Il usuellement préférable de garder un plus grande nombre d’axes afin de couvrir au moins 80 à 90 % de la variance11. De son côté, dist.dudi prends en compte l’ensemble des axes pour calculer la matrice des distances. On peut reproduire cela avec FactoMineR en indiquant ncp=Inf lors du calcul de l’ACM.

acm2 <- MCA(d2[complete.cases(d2), ], ncp = Inf, graph = FALSE)
cah <- HCPC(acm2, nb.clust = -1, graph = FALSE)

On obtient bien cette fois-ci le même résultat.

plot(cah, choice = "tree")
Dendrogramme obtenu avec HCPC (tous les axes)

D’autres graphiques sont disponibles, en faisant varier la valeur de l’argument choice :

plot(cah, choice = "3D.map")
Représentation en 3 dimensions du dendrogramme
plot(cah, choice = "bar")
Gains d’inertie
plot(cah, choice = "map")
Projection des catégories sur le plan factoriel

L’objet renvoyé par HCPC contient de nombreuses informations. La partition peut notamment être récupérée avec cah$data.clust$clust. Il y a également diverses statistiques pour décrire les catégories.

cah
**Results for the Hierarchical Clustering on Principal Components**
   name                   
1  "$data.clust"          
2  "$desc.var"            
3  "$desc.var$test.chi2"  
4  "$desc.axes$category"  
5  "$desc.axes"           
6  "$desc.axes$quanti.var"
7  "$desc.axes$quanti"    
8  "$desc.ind"            
9  "$desc.ind$para"       
10 "$desc.ind$dist"       
11 "$call"                
12 "$call$t"              
   description                                              
1  "dataset with the cluster of the individuals"            
2  "description of the clusters by the variables"           
3  "description of the cluster var. by the categorical var."
4  "description of the clusters by the categories."         
5  "description of the clusters by the dimensions"          
6  "description of the cluster var. by the axes"            
7  "description of the clusters by the axes"                
8  "description of the clusters by the individuals"         
9  "parangons of each clusters"                             
10 "specific individuals"                                   
11 "summary statistics"                                     
12 "description of the tree"                                
freq(cah$data.clust$clust)

  1. Pour une présentation de ces différentes distances, on pourra se référer à http://old.biodiversite.wallonie.be/outils/methodo/similarite_distance.htm ou encore à ce support de cours par D. Chessel, J. Thioulouse et A.B. Dufour disponible à http://pbil.univ-lyon1.fr/R/pdf/stage7.pdf.

  2. Cette même fonction peut aussi être utilisée pour calculer une distance après une analyse en composantes principales ou une analyse mixte de Hill et Smith.

  3. Voir Gower, J. (1971). A General Coefficient of Similarity and Some of Its Properties. Biometrics, 27(4), 857-871. doi:10.2307/2528823 (http://www.jstor.org/stable/2528823).

  4. Pour une description mathématique plus détaillée de cette fonction, notamment en cas de valeur manquante, se référer à l’article original de Gower précédemment cité.

  5. On pourra consulter le cours de FG Carpentier déjà cité ou bien des ouvrages d’analyse statistique.

  6. Ward, J. (1963). Hierarchical Grouping to Optimize an Objective Function. Journal of the American Statistical Association, 58(301), 236-244. doi:10.2307/2282967. (http://www.jstor.org/stable/2282967)

  7. Voir par exemple la discussion, en anglais, sur Wikipedia concernant la page présentant la méthode Ward : https://en.wikipedia.org/wiki/Talk:Ward%27s_method

  8. Depuis la version 3.1 de R. L’option method = "ward.D" correspondant à la version disponible dans les versions précédentes de R. Mais il est à noter que la méthode décrite par Ward dans son article de 1963 correspond en réalité à method = "ward.D2.

  9. Voir http://addicted2or.free.fr/packages/A2R/lastVersion/R/code.R.

  10. Pour une présentation succincte, voir l’introduction de l’extension sur https://cran.r-project.org/web/packages/dendextend/vignettes/introduction.html (en anglais).

  11. Voir http://factominer.free.fr/classical-methods/classification-hierarchique-sur-composantes-principales.html

Effets d’interaction dans un modèle

Dans un modèle statistique classique, on fait l’hypothèse implicite que chaque variable explicative est indépendante des autres. Cependant, cela ne se vérifie pas toujours. Par exemple, l’effet de l’âge peut varier en fonction du sexe. Il est dès lors nécessaire de prendre en compte dans son modèle les effets d’interaction1.

Exemple d’interaction

Reprenons le modèle que nous avons utilisé dans le chapitre sur la régression logistique.

library(questionr)
data(hdv2003)
d <- hdv2003
d$sexe <- relevel(d$sexe, "Femme")
d$grpage <- cut(d$age, c(16, 25, 45, 65, 99), right = FALSE, include.lowest = TRUE)
d$etud <- d$nivetud
levels(d$etud) <- c(
  "Primaire", "Primaire", "Primaire",
  "Secondaire", "Secondaire", "Technique/Professionnel",
  "Technique/Professionnel", "Supérieur"
)
d$etud <- addNAstr(d$etud, "Manquant")
library(labelled)
var_label(d$sport) <- "Pratique du sport ?"
var_label(d$sexe) <- "Sexe"
var_label(d$grpage) <- "Groupe d'âges"
var_label(d$etud) <- "Niveau d'étude"
var_label(d$relig) <- "Pratique religieuse"
var_label(d$heures.tv) <- "Nombre d'heures passées devant la télévision par jour"

Nous avions alors exploré les facteurs associés au fait de pratiquer du sport.

mod <- glm(sport ~ sexe + grpage + etud + heures.tv + relig, data = d, family = binomial())
library(gtsummary)
tbl_regression(mod, exponentiate = TRUE)
Caractéristique OR1 95% CI1 p-value
Sexe
Femme
Homme 1,55 1,26 – 1,91 <0,001
Groupe d'âges
[16,25)
[25,45) 0,66 0,42 – 1,03 0,065
[45,65) 0,34 0,21 – 0,54 <0,001
[65,99] 0,25 0,15 – 0,43 <0,001
Niveau d'étude
Primaire
Secondaire 2,59 1,77 – 3,83 <0,001
Technique/Professionnel 2,86 1,98 – 4,17 <0,001
Supérieur 6,63 4,55 – 9,80 <0,001
Manquant 8,59 4,53 – 16,6 <0,001
Nombre d'heures passées devant la télévision par jour 0,89 0,83 – 0,95 <0,001
Pratique religieuse
Pratiquant regulier
Pratiquant occasionnel 0,98 0,68 – 1,42 >0,9
Appartenance sans pratique 0,99 0,71 – 1,40 >0,9
Ni croyance ni appartenance 0,81 0,55 – 1,18 0,3
Rejet 0,68 0,39 – 1,19 0,2
NSP ou NVPR 0,92 0,40 – 2,02 0,8

1 OR = rapport de cotes, CI = intervalle de confiance

Selon les résultats de notre modèle, les hommes pratiquent plus un sport que les femmes et la pratique du sport diminue avec l’âge. Pour représenter les effets différentes variables, on peut avoir recours à la fonction allEffects de l’extension effects.

library(effects)
plot(allEffects(mod))
Représentation graphique des effets du modèle

Cependant, l’effet de l’âge est-il le même selon le sexe ? Nous allons donc introduire une interaction entre l’âge et le sexe dans notre modèle, ce qui sera représenté par sexe * grpage dans l’équation du modèle.

mod2 <- glm(sport ~ sexe * grpage + etud + heures.tv + relig, data = d, family = binomial())
tbl_regression(mod2, exponentiate = TRUE)
Caractéristique OR1 95% CI1 p-value
Sexe
Femme
Homme 5,20 2,46 – 11,7 <0,001
Groupe d'âges
[16,25)
[25,45) 1,02 0,59 – 1,80 >0,9
[45,65) 0,61 0,34 – 1,10 0,10
[65,99] 0,46 0,23 – 0,92 0,027
Niveau d'étude
Primaire
Secondaire 2,60 1,77 – 3,85 <0,001
Technique/Professionnel 2,88 1,99 – 4,21 <0,001
Supérieur 6,77 4,64 – 10,0 <0,001
Manquant 9,02 4,68 – 17,8 <0,001
Nombre d'heures passées devant la télévision par jour 0,89 0,83 – 0,95 <0,001
Pratique religieuse
Pratiquant regulier
Pratiquant occasionnel 0,99 0,68 – 1,43 >0,9
Appartenance sans pratique 1,02 0,73 – 1,44 0,9
Ni croyance ni appartenance 0,83 0,57 – 1,22 0,3
Rejet 0,68 0,38 – 1,19 0,2
NSP ou NVPR 0,93 0,40 – 2,04 0,9
Sexe * Groupe d'âges
Homme * [25,45) 0,31 0,13 – 0,70 0,006
Homme * [45,65) 0,24 0,10 – 0,54 <0,001
Homme * [65,99] 0,23 0,09 – 0,59 0,003

1 OR = rapport de cotes, CI = intervalle de confiance

Commençons par regarder les effets du modèle.

plot(allEffects(mod2))
Représentation graphique des effets du modèle avec interaction entre le sexe et le groupe d’âge

Sur ce graphique, on voit que l’effet de l’âge sur la pratique d’un sport est surtout marqué chez les hommes. Chez les femmes, le même effet est observé, mais dans une moindre mesure et seulement à partir de 45 ans.

On peut tester si l’ajout de l’interaction améliore significativement le modèle avec anova.

anova(mod2, test = "Chisq")

Jetons maintenant un oeil aux coefficients du modèle. Pour rendre les choses plus visuelles, nous aurons recours à ggcoef de l’extension GGally.

library(GGally)
ggcoef(mod2, exponentiate = TRUE)
Représentation graphique des coefficients du modèle avec interaction entre le sexe et le groupe d’âge

Concernant l’âge et le sexe, nous avons trois séries de coefficients : trois coefficients (grpage[25,45), grpage[45,65) et grpage[65,99]) qui correspondent à l’effet global de la variable âge, un coefficient (sexeHomme)pour l’effet global du sexe et trois coefficients qui sont des moficateurs de l’effet d’âge pour les hommes (grpage[25,45), grpage[45,65) et grpage[65,99]).

Pour bien interpréter ces coefficients, il faut toujours avoir en tête les modalités choisies comme référence pour chaque variable. Supposons une femme de 60 ans, dont toutes lautres variables correspondent aux modalités de référence (c’est donc une pratiquante régulière, de niveau primaire, qui ne regarde pas la télévision). Regardons ce que prédit le modèle quant à sa probabilité de faire du sport au travers d’une représentation graphique

library(breakDown)
library(ggplot2)
logit <- function(x) exp(x) / (1 + exp(x))
nouvelle_observation <- d[1, ]
nouvelle_observation$sexe[1] <- "Femme"
nouvelle_observation$grpage[1] <- "[45,65)"
nouvelle_observation$etud[1] <- "Primaire"
nouvelle_observation$relig[1] <- "Pratiquant regulier"
nouvelle_observation$heures.tv[1] <- 0
plot(
  broken(mod2, nouvelle_observation, predict.function = betas),
  trans = logit
) + ylim(0, 1) + ylab("Probabilité de faire du sport")
Scale for 'y' is already present. Adding another scale
for 'y', which will replace the existing scale.
Représentation graphique de l’estimation de la probabilité de faire du sport pour une femme de 60 ans

En premier lieu, l’intercept s’applique et permet de déterminer la probabilité de base de faire du sport (si toutes les variables sont à leur valeur de référence). Femme étant la modalité de référence pour la variable sexe, cela ne modifie pas le calcul de la probabilité de faire du sport. Par contre, il y a une modification induite par la modalité 45-65 de la variable grpage.

Regardons maintenant la situation d’un homme de 20 ans.

nouvelle_observation$sexe[1] <- "Homme"
nouvelle_observation$grpage[1] <- "[16,25)"
plot(
  broken(mod2, nouvelle_observation, predict.function = betas),
  trans = logit
) + ylim(0, 1) + ylab("Probabilité de faire du sport")
Scale for 'y' is already present. Adding another scale
for 'y', which will replace the existing scale.
Représentation graphique de l’estimation de la probabilité de faire du sport pour un homme de 20 ans

Nous sommes à la modalité de référence pour l’âge par contre il y a un effet important du sexe. Le coefficient associé globalement à la variable sexe correspond donc à l’effet du sexe à la modalité de référence du groupe d’âges.

La situation est différente pour un homme de 60 ans.

nouvelle_observation$grpage[1] <- "[45,65)"
plot(
  broken(mod2, nouvelle_observation, predict.function = betas),
  trans = logit
) + ylim(0, 1) + ylab("Probabilité de faire du sport")
Scale for 'y' is already present. Adding another scale
for 'y', which will replace the existing scale.
Représentation graphique de l’estimation de la probabilité de faire du sport pour un homme de 60 ans

Cette fois-ci, il y a plusieurs modifications d’effet. On applique en effet à la fois le coefficient sexe = Homme (effet du sexe pour les 15-24 ans), le coefficient grpage = [45-65) qui est l’effet de l’âge pour les femmes de 45-64 ans et le coefficient sexe:grpage = Homme:[45-65) qui indique l’effet spécifique qui s’applique aux hommes de 45-64, d’une part par rapport aux femmes du même et d’autre part par rapport aux hommes de 16-24 ans. L’effet des coefficients d’interaction doivent donc être interprétés par rapport aux autres coefficients du modèle qui s’appliquent, en tenant compte des modalités de référence.

Il est cependant possible d’écrire le même modèle différemment. En effet, sexe * grpage dans la formule du modèle est équivalent à l’écriture sexe + grpage + sexe:grpage, c’est-à-dire à modéliser un coefficient global pour chaque variable plus un des coefficients d’interaction. On aurait pu demander juste des coefficients d’interaction, en ne mettant que sexe:grpage.

mod3 <- glm(sport ~ sexe:grpage + etud + heures.tv + relig, data = d, family = binomial())
tbl_regression(mod3, exponentiate = TRUE)
Caractéristique OR1 95% CI1 p-value
Niveau d'étude
Primaire
Secondaire 2,60 1,77 – 3,85 <0,001
Technique/Professionnel 2,88 1,99 – 4,21 <0,001
Supérieur 6,77 4,64 – 10,0 <0,001
Manquant 9,02 4,68 – 17,8 <0,001
Nombre d'heures passées devant la télévision par jour 0,89 0,83 – 0,95 <0,001
Pratique religieuse
Pratiquant regulier
Pratiquant occasionnel 0,99 0,68 – 1,43 >0,9
Appartenance sans pratique 1,02 0,73 – 1,44 0,9
Ni croyance ni appartenance 0,83 0,57 – 1,22 0,3
Rejet 0,68 0,38 – 1,19 0,2
NSP ou NVPR 0,93 0,40 – 2,04 0,9
Sexe * Groupe d'âges
Femme * [16,25) 1,82 0,92 – 3,58 0,083
Homme * [16,25) 9,46 4,34 – 21,8 <0,001
Femme * [25,45) 1,86 1,17 – 3,00 0,009
Homme * [25,45) 3,02 1,87 – 4,96 <0,001
Femme * [45,65) 1,11 0,69 – 1,80 0,7
Homme * [45,65) 1,35 0,84 – 2,21 0,2
Femme * [65,99] 0,84 0,47 – 1,50 0,6
Homme * [65,99]

1 OR = rapport de cotes, CI = intervalle de confiance

Au sens strict, ce modèle explique tout autant le phénomène étudié que le modèle précédent. On peut le vérifier facilement avec anova.

anova(mod2, mod3, test = "Chisq")

De même, les effets modélisés sont les mêmes.

plot(allEffects(mod3))
Représentation graphique des effets du modèle avec interaction simple entre le sexe et le groupe d’âge

Par contre, regardons d’un peu plus près les coefficients de ce nouveau modèle. Nous allons voir que leur interprétation est légèrement différente.

ggcoef(mod3, exponentiate = TRUE)
Warning: Removed 1 rows containing missing values
(geom_errorbarh).
Warning: Removed 1 rows containing missing values
(geom_point).
Représentation graphique des coefficients du modèle avec interaction simple entre le sexe et le groupe d’âge

Cette fois-ci, il n’y a plus de coefficients globaux pour la variable sexe ni pour grpage mais des coefficients pour chaque combinaison de ces deux variables.

plot(
  broken(mod3, nouvelle_observation, predict.function = betas),
  trans = logit
) + ylim(0, 1) + ylab("Probabilité de faire du sport")
Scale for 'y' is already present. Adding another scale
for 'y', which will replace the existing scale.
Représentation graphique de l’estimation de la probabilité de faire du sport pour un homme de 40 ans

Cette fois-ci, le coefficient d’interaction fourrnit l’effet global du sexe et de l’âge, et non plus la modification de cette combinaison par rapport aux coefficients globaux. Leur sens est donc différent et il faudra les interpréter en conséquence.

Un second exemple d’interaction

Intéressons-nous maintenant à l’interaction entre le sexe et le niveau d’étude. L’effet du niveau d’étude diffère-t-il selon le sexe ?

mod4 <- glm(sport ~ sexe * etud + grpage + heures.tv + relig, data = d, family = binomial())

Regardons d’abord les effets.

plot(allEffects(mod4))
Représentation graphique des effets du modèle avec interaction entre le sexe et le niveau d’étude

À première vue, l’effet du niveau d’étude semble être le même chez les hommes et chez les femmes. Ceci dit, cela serait peut être plus lisible si l’on superposait les deux sexe sur un même graphique. Nous allons utiliser la fonction ggeffect de l’extension ggeffects qui permets de récupérer les effets calculés avec effect dans un format utilisable avec ggplot2.

library(ggeffects)
plot(ggeffect(mod4, c("etud", "sexe")))
Effets du niveau d’étude selon le sexe

Cela confirme ce que l’on suppose. Regardons les coefficients du modèle.

ggcoef(mod4, exponentiate = TRUE)
Représentation graphique des coefficients du modèle avec interaction simple entre le sexe et le niveau d’étude
tbl_regression(mod4, exponentiate = TRUE)
Caractéristique OR1 95% CI1 p-value
Sexe
Femme
Homme 1,42 0,77 – 2,58 0,3
Niveau d'étude
Primaire
Secondaire 2,25 1,35 – 3,82 0,002
Technique/Professionnel 3,09 1,90 – 5,17 <0,001
Supérieur 6,59 4,02 – 11,1 <0,001
Manquant 5,21 2,42 – 11,4 <0,001
Groupe d'âges
[16,25)
[25,45) 0,66 0,42 – 1,04 0,071
[45,65) 0,34 0,21 – 0,55 <0,001
[65,99] 0,25 0,15 – 0,43 <0,001
Nombre d'heures passées devant la télévision par jour 0,89 0,83 – 0,95 <0,001
Pratique religieuse
Pratiquant regulier
Pratiquant occasionnel 0,98 0,67 – 1,42 0,9
Appartenance sans pratique 1,01 0,72 – 1,43 >0,9
Ni croyance ni appartenance 0,83 0,56 – 1,21 0,3
Rejet 0,70 0,40 – 1,23 0,2
NSP ou NVPR 0,90 0,39 – 1,98 0,8
Sexe * Niveau d'étude
Homme * Secondaire 1,38 0,65 – 2,93 0,4
Homme * Technique/Professionnel 0,87 0,44 – 1,75 0,7
Homme * Supérieur 1,01 0,49 – 2,07 >0,9
Homme * Manquant 4,28 1,32 – 15,8 0,020

1 OR = rapport de cotes, CI = intervalle de confiance

Si les coefficients associés au niveau d’étude sont significatifs, ceux de l’interaction ne le sont pas (sauf sexeHomme:etudManquant) et celui associé au sexe, précédemment significatif ne l’est plus. Testons avec anova si l’interaction est belle et bien significative.

anova(mod4, test = "Chisq")

L’interaction est bien significative mais faiblement. Vu que l’effet du niveau d’étude reste nénamoins très similaire selon le sexe, on peut se demander s’il est pertinent de la conserver.

Explorer les différentes interactions possibles

Il peut y avoir de multiples interactions dans un modèle, d’ordre 2 (entre deux variables) ou plus (entre trois variables ou plus). Il est dès lors tentant de tester les multiples interactions possibles de manière itératives afin d’identifier celles à retenir. C’est justement le but de la fonction glmulti de l’extension du même nom. glmulti permets de tester toutes les combinaisons d’interactions d’ordre 2 dans un modèle, en retenant le meilleur modèle à partir d’un critère spécifié (par défaut l’AIC). ATTENTION : le temps de calcul de glmulti peut-être long.

library(glmulti)
glmulti(sport ~ sexe + grpage + etud + heures.tv + relig, data = d, family = binomial())
Initialization...
TASK: Exhaustive screening of candidate set.
Fitting...

After 50 models:
Best model: sport~1+grpage+heures.tv+sexe:heures.tv+grpage:heures.tv+etud:heures.tv
Crit= 2284.87861987263
Mean crit= 2406.80086471225

After 100 models:
Best model: sport~1+etud+heures.tv+grpage:heures.tv
Crit= 2267.79462883348
Mean crit= 2360.46497457747

After 150 models:
Best model: sport~1+grpage+etud+heures.tv+sexe:heures.tv
Crit= 2228.88574082404
Mean crit= 2286.60589884071

After 200 models:
Best model: sport~1+grpage+etud+heures.tv+sexe:heures.tv
Crit= 2228.88574082404
Mean crit= 2254.99359340075

After 250 models:
Best model: sport~1+sexe+grpage+etud+heures.tv+etud:sexe+sexe:heures.tv
Crit= 2226.00088609349
Mean crit= 2241.76611580481

After 300 models:
Best model: sport~1+sexe+grpage+etud+heures.tv+grpage:sexe+sexe:heures.tv
Crit= 2222.67161519005
Mean crit= 2234.95020358944

On voit qu’au bout d’un moment, l’algorithme se statibilise autour d’un modèle comportant une interaction entre le sexe et l’âge d’une part et entre le sexe et le nombre d’heures passées quotidiennement devant la télé. On voit également que la variable religion a été retirée du modèle final.

best <- glm(sport ~ 1 + sexe + grpage + etud + heures.tv + grpage:sexe + sexe:heures.tv, data = d, family = binomial())
odds.ratio(best)
Waiting for profiling to be done...
ggcoef(best, exponentiate = TRUE)
Représentation graphique des coefficients du modèle avec interaction entre le sexe, le niveau d’étude et le nombre d’heures passées devant la télévision
plot(allEffects(best))
Représentation graphique des effets du modèle avec interaction entre le sexe, le niveau d’étude et le nombre d’heures passées devant la télévision

Pour aller plus loin

Il y a d’autres extensions dédiées à l’analyse des interactions d’un modèle, de même que de nombreux supports de cours en ligne dédiés à cette question.

On pourra en particulier se référer à la vignette inclue avec l’extension phia : https://cran.r-project.org/web/packages/phia/vignettes/phia.pdf.


  1. Pour une présentation plus statistique et mathématique des effets d’interaction, on pourra se référer au cours de Jean-François Bickel disponible en ligne.

Multicolinéarité dans la régression

Dans une régression, la multicolinéarité est un problème qui survient lorsque certaines variables de prévision du modèle mesurent le même phénomène. Une multicolinéarité prononcée s’avère problématique, car elle peut augmenter la variance des coefficients de régression et les rendre instables et difficiles à interpréter. Les conséquences de coefficients instables peuvent être les suivantes :

  • les coefficients peuvent sembler non significatifs, même lorsqu’une relation significative existe entre le prédicteur et la réponse ;
  • les coefficients de prédicteurs fortement corrélés varieront considérablement d’un échantillon à un autre ;
  • lorsque des termes d’un modèle sont fortement corrélés, la suppression de l’un de ces termes aura une incidence considérable sur les coefficients estimés des autres. Les coefficients des termes fortement corrélés peuvent même présenter le mauvais signe.

La multicolinéarité n’a aucune incidence sur l’adéquation de l’ajustement, ni sur la qualité de la prévision. Cependant, les coefficients individuels associés à chaque variable explicative ne peuvent pas être interprétés de façon fiable.

Définition

Au sens strict, on parle de multicolinéarité parfaite lorsqu’une des variables explicatives d’un modèle est une combinaison linéraire d’une ou plusieurs autres variables explicatives introduites dans le même modèle. L’absence de multicolinéarité parfaite est une des conditions requises pour pouvoir estimer un modèle linéaire et, par extension, un modèle linéaire généralisé (dont les modèles de régression logistique).

Dans les faits, une multicolinéarité parfaite n’est quasiment jamais observée. Mais une forte multicolinéarité entre plusieurs variables peut poser problème dans l’estimation et l’interprétation d’un modèle.

Une erreur fréquente est de confondre multicolinéarité et corrélation. Si des variables colinéaires sont de facto fortement corrélées entre elles, deux variables corrélées ne sont pas forcément colinéaires. En termes non statistiques, il y a colinéarité lorsque deux ou plusieurs variables mesurent la même chose.

Prenons un exemple. Nous étudions les complications après l’accouchement dans différentes maternités d’un pays en développement. On souhaite mettre dans le modèle, à la fois le milieu de résidence (urbain ou rural) et le fait qu’il y ait ou non un médecin dans la clinique. Or, dans la zone d’enquête, les maternités rurales sont dirigées seulement par des sage-femmes tandis que l’on trouve un médecin dans toutes les maternités urbaines sauf une. Dès lors, dans ce contexte précis, le milieu de résidence prédit presque totalement la présence d’un médecin et on se retrouve face à une multicolinéarité (qui serait même parfaite s’il n’y avait pas une clinique urbaine sans médecin). On ne peut donc distinguer l’effet de la présence d’un médecin de celui du milieu de résidence et il ne faut mettre qu’une seule de ces deux variables dans le modèle, sachant que du point de vue de l’interprétation elle capturera à la fois l’effet de la présence d’un médecin et celui du milieu de résidence.

Par contre, si dans notre région d’étude, seule la moitié des maternités urbaines disposait d’un médecin, alors le milieu de résidence n’aurait pas été suffisant pour prédire la présence d’un médecin. Certes, les deux variables seraient corrélées mais pas colinéaires. Un autre exemple de corrélation sans colinéarité, c’est la relation entre milieu de résidence et niveau d’instruction. Il y a une corrélation entre ces deux variables, les personnes résidant en ville étant généralement plus instruites. Cependant, il existe également des personnes non instruites en ville et des personnes instruites en milieu rural. Le milieu de résidence n’est donc pas suffisant pour prédire le niveau d’instruction.

Mesure de la colinéarité

Il existe différentes mesures de la multicolinéarité. L’extension mctest en fournie plusieurs, mais elle n’est utilisable que si l’ensemble des variables explicatives sont de type numérique.

L’approche la plus classique consiste à examiner les facteurs d’inflation de la variance (FIV) ou variance inflation factor (VIF) en anglais. Les FIV estimenent de combien la variance d’un coefficient est augmentée en raison d’une relation linéaire avec d’autres prédicteurs. Ainsi, un FIV de 1,8 nous dit que la variance de ce coefficient particulier est supérieure de 80 % à la variance que l’on aurait dû observer si ce facteur n’est absolument pas corrélé aux autres prédicteurs.

Si tous les FIV sont égaux à 1, il n’existe pas de multicolinéarité, mais si certains FIV sont supérieurs à 1, les prédicteurs sont corrélés. Il n’y a pas de consensus sur la valeur au-delà de laquelle on doit considérer qu’il y a multicolinéarité. Certains auteurs, comme Paul Allison1, disent regarder plus en détail les variables avec un FIV supérieur à 2,5. D’autres ne s’inquiètent qu’à partir de 5. Il n’existe pas de test statistique qui permettrait de dire s’il y a colinéarité ou non2.

L’extension car fournit une fonction vif permettant de calculer les FIV à partir d’un modèle. Elle implémente même une version généralisée permettant de considérer des facteurs catégoriels et des modèles linéaires généralisés comme la régression logistique.

Reprenons, pour exemple, un modèle logistique que nous avons déjà abordé dans d’autres chapitres.

library(questionr)
data(hdv2003)
d <- hdv2003
d$sexe <- relevel(d$sexe, "Femme")
d$grpage <- cut(d$age, c(16, 25, 45, 65, 99), right = FALSE, include.lowest = TRUE)
d$etud <- d$nivetud
levels(d$etud) <- c(
  "Primaire", "Primaire", "Primaire", "Secondaire", "Secondaire",
  "Technique/Professionnel", "Technique/Professionnel", "Supérieur"
)
d$etud <- addNAstr(d$etud, "Manquant")
mod <- glm(sport ~ sexe + grpage + etud + heures.tv + relig, data = d, family = binomial())

Le calcul des FIV se fait simplement en passant le modèle à la fonction vif.

library(car)
vif(mod)
           GVIF Df GVIF^(1/(2*Df))
sexe      1.048  1           1.024
grpage    1.842  3           1.107
etud      1.848  4           1.080
heures.tv 1.062  1           1.031
relig     1.121  5           1.011

Dans notre exemple, tous les FIV sont proches de 1. Il n’y a donc pas de problème potentiel de colinéarité à explorer.

La multicolinéarité est-elle toujours un problème ?

Là encore, il n’y a pas de consensus sur cette question. Certains analystes considèrent que tout modèle où certains prédicteurs seraient colinéaires n’est pas valable. Dans un billet sur internet, Paul Allison évoque quant à lui des situations où la multicolinéarité peut être ignorée en toute sécurité. Le texte ci-dessous est une traduction du billet de Paul Allison.

1. Les variables avec des FIV élevés sont des variables de contrôle, et les variables d’intérêt n’ont pas de FIV élevés.

Voici le problème de la multicollinéarité : ce n’est un problème que pour les variables qui sont colinéaires. Il augmente les erreurs-types de leurs coefficients et peut rendre ces coefficients instables de plusieurs façons. Mais tant que les variables colinéaires ne sont utilisées que comme variables de contrôle, et qu’elles ne sont pas colinéaires avec vos variables d’intérêt, il n’y a pas de problème. Les coefficients des variables d’intérêt ne sont pas affectés et la performance des variables de contrôle n’est pas altérée.

Voici un exemple tiré de ces propres travaux : l’échantillon est constitué de collèges américains, la variable dépendante est le taux d’obtention de diplôme et la variable d’intérêt est un indicateur (factice) pour les secteurs public et privé. Deux variables de contrôle sont les scores moyens au SAT et les scores moyens à l’ACT pour l’entrée en première année. Ces deux variables ont une corrélation supérieure à ,9, ce qui correspond à des FIV d’au moins 5,26 pour chacune d’entre elles. Mais le FIV pour l’indicateur public/privé n’est que de 1,04. Il n’y a donc pas de problème à se préoccuper et il n’est pas nécessaire de supprimer l’un ou l’autre des deux contrôles, à condition que l’on ne cherche pas à interpréter ou comparer l’un par rapport à l’autre les coefficients de ces deux variables de contrôle.

2. Les FIV élevés sont causés par l’inclusion de puissances ou de produits d’autres variables.

Si vous spécifiez un modèle de régression avec x et x2, il y a de bonnes chances que ces deux variables soient fortement corrélées. De même, si votre modèle a x, z et xz, x et z sont susceptibles d’être fortement corrélés avec leur produit. Il n’y a pas de quoi s’inquiéter, car la valeur p de xz n’est pas affectée par la multicollinéarité. Ceci est facile à démontrer : vous pouvez réduire considérablement les corrélations en centrant les variables (c’est-à-dire en soustrayant leurs moyennes) avant de créer les puissances ou les produits. Mais la valeur p pour x2 ou pour xz sera exactement la même, que l’on centre ou non. Et tous les résultats pour les autres variables (y compris le R2 mais sans les termes d’ordre inférieur) seront les mêmes dans les deux cas. La multicollinéarité n’a donc pas de conséquences négatives.

3. Les variables avec des FIV élevés sont des variables indicatrices (factices) qui représentent une variable catégorielle avec trois catégories ou plus.

Si la proportion de cas dans la catégorie de référence est faible, les variables indicatrices auront nécessairement des FIV élevés, même si la variable catégorielle n’est pas associée à d’autres variables dans le modèle de régression.

Supposons, par exemple, qu’une variable de l’état matrimonial comporte trois catégories : actuellement marié, jamais marié et anciennement marié. Vous choisissez anciennement marié comme catégorie de référence, avec des variables d’indicateur pour les deux autres. Ce qui se passe, c’est que la corrélation entre ces deux indicateurs devient plus négative à mesure que la fraction de personnes dans la catégorie de référence diminue. Par exemple, si 45 % des personnes ne sont jamais mariées, 45 % sont mariées et 10 % sont anciennement mariées, les valeurs du FIV pour les personnes mariées et les personnes jamais mariées seront d’au moins 3,0.

Est-ce un problème ? Eh bien, cela signifie que les valeurs p des variables indicatrices peuvent être élevées. Mais le test global selon lequel tous les indicateurs ont des coefficients de zéro n’est pas affecté par des FIV élevés. Et rien d’autre dans la régression n’est affecté. Si vous voulez vraiment éviter des FIV élevés, il suffit de choisir une catégorie de référence avec une plus grande fraction des cas. Cela peut être souhaitable pour éviter les situations où aucun des indicateurs individuels n’est statistiquement significatif, même si l’ensemble des indicateurs est significatif.


  1. https://statisticalhorizons.com/multicollinearity

  2. Pour plus de détails, voir ce post de Davig Giles qui explique pourquoi ce n’est pas possible.

Analyse de survie

Ressources en ligne

L’extension centrale pour l’analyse de survie est survival.

Un très bon tutoriel (en anglais et en 3 étapes), introduisant les concepts de l’analyse de survie, des courbes de Kaplan-Meier et des modèles de Cox et leur mise en oeuvre pratique sous R est disponible en ligne :

Pour un autre exemple (toujours en anglais) d’analyse de survie avec survival, on pourra se référer à https://rpubs.com/vinubalan/hrsurvival.

Pour représenter vos résultats avec ggplot2, on pourra avoir recours à l’extension survminer présentée en détails sur son site officiel (en anglais) : http://www.sthda.com/english/rpkgs/survminer/. On pourra également avoir recours à la fonction ggsurv de l’extension GGally présentée à l’adresse http://ggobi.github.io/ggally/#ggallyggsurv.

A noter, il est possible d’utiliser la fonction step sur un modèle de Cox, pour une sélection pas à pas d’un meilleur modèle basé sur une minimisation de l’AIC (voir le chapitre sur la régression logistique).

L’excellente extension broom peut également être utilisée sur des modèles de survie (Kaplan-Meier ou Cox) pour en convertir les résultats sous la forme d’un tableau de données.

Pour approfondir les possibilités offertes par l’extension survival, on pourra également consulter les différentes vignettes fournies avec l’extension (voir https://cran.r-project.org/package=survival).

Un exemple concret : mortalité infanto-juvénile

Dans cet exemple, nous allons utiliser le jeu de données fecondite fourni par l’extension questionr. Ce jeu de données comporte trois tableaux de données : menages, femmes et enfants.

Nous souhaitons étudier ici la survie des enfants entre la naissance et l’âge de 5 ans. Dans un premier temps, nous comparerons la survie des jeunes filles et des jeunes garçons. Dans un second temps, nous procéderons à une analyse multivariée en prenant en compte les variables suivantes :

  • sexe de l’enfant
  • milieu de résidence
  • niveau de vie du ménage
  • structure du ménage
  • niveau d’éducation de la mère
  • âge de la mère à la naissance de l’enfant
  • enfin, une variable un peu plus compliquée, à savoir si le rang de naissance de l’enfant (second, troisième, quatrième, etc.) est supérieur au nombre idéal d’enfants selon la mère.

Nous allons préparer les données selon deux approches : soit en utilisant l’extension data.table (voir le chapitre dédié à data.table), soit en utilisant l’extension dplyr (voir le chapitre sur dplyr).

Chargeons les données en mémoire et listons les variables disponibles.

library(questionr, quietly = TRUE)
data(fecondite)
lookfor(menages)
lookfor(femmes)
lookfor(enfants)

Préparation des données avec data.table

Tout d’abord, regardons sous quel format elles sont stockées.

class(menages)
[1] "tbl_df"     "tbl"        "data.frame"
describe(menages)
[1814 obs. x 5 variables] tbl_df tbl data.frame

$id_menage: Identifiant du ménage
numeric: 1 2 3 4 5 6 7 8 9 10 ...
min: 1 - max: 1814 - NAs: 0 (0%) - 1814 unique values

$taille: Taille du ménage (nombre de membres)
numeric: 7 3 6 5 7 6 15 6 5 19 ...
min: 1 - max: 31 - NAs: 0 (0%) - 30 unique values

$sexe_chef: Sexe du chef de ménage
labelled double: 2 1 1 1 1 2 2 2 1 1 ...
min: 1 - max: 2 - NAs: 0 (0%) - 2 unique values
2 value labels: [1] homme [2] femme

$structure: Structure démographique du ménage
labelled double: 4 2 5 4 4 4 5 2 5 5 ...
min: 1 - max: 5 - NAs: 0 (0%) - 5 unique values
6 value labels: [0] pas d'adulte [1] un adulte [2] deux adultes de sexe opposé [3] deux adultes de même sexe [4] trois adultes ou plus avec lien de parenté [5] adultes sans lien de parenté

$richesse: Niveau de vie (quintiles)
labelled double: 1 2 2 1 1 3 2 5 4 3 ...
min: 1 - max: 5 - NAs: 0 (0%) - 5 unique values
5 value labels: [1] très pauvre [2] pauvre [3] moyen [4] riche [5] très riche

Les tableaux de données sont au format tibble (c’est-à-dire sont de la classe tbl_df) et les variables catégorielles sont du type haven_labelled (voir le chapitre sur les vecteurs labellisés). Ce format correspond au format de données si on les avait importées depuis SPSS avec l’extension haven (voir le chapitre sur l’import de données).

En premier lieu, il nous faut convertir les tableaux de données au format data.table, ce qui peut se faire avec la fonction setDT. Par ailleurs, nous allons également charger en mémoire l’extension labelled pour la gestion des vecteurs labellisés.

library(labelled)
library(data.table)
setDT(menages)
setDT(femmes)
setDT(enfants)

En premier lieu, il nous faut calculer la durée d’observation des enfants, à savoir le temps passé entre la date de naissance (variable du fichier enfants) et la date de passation de l’entretien (fournie par le tableau de données femmes). Pour récupérer des variables du fichier femmes dans le fichier enfants, nous allons procéder à une fusion de table (voir le chapitre dédié). Pour le calcul de la durée d’observation, nous allons utiliser le package lubridate (voir le chapitre calculer un âge et celui sur la gestion des dates). Nous effectuerons l’analyse en mois (puisque l’âge au décès est connu en mois). Dès lors, la durée d’observation sera calculée en mois.

enfants <- merge(
  enfants,
  femmes[, .(id_femme, date_entretien)],
  by = "id_femme",
  all.x = TRUE
)

# duree observation en mois
library(lubridate, quietly = TRUE)
enfants[, duree_observation := time_length(interval(date_naissance, date_entretien), unit = "months")]

ATTENTION : il y 11 enfants soi-disant nés après la date d’enquête ! Quelle que soit l’enquête, il est rare de ne pas observer d’incohérences. Dans le cas présent, il est fort possible que la date d’entretien puisse parfois être erronnée (par exemple si l’enquêteur a inscrit une date sur le questionnaire papier le jour du recensement du ménage mais n’ai pu effectué le questionnaire individuel que plus tard). Nous décidons ici de procéder à une correction en ajoutant un mois aux dates d’entretien problématiques. D’autres approches auraient pu être envisagées, comme par exemple exclure ces observations problématiques. Cependant, cela aurait impacté le calcul du range de naissance pour les autres enfants issus de la même mère. Quoiqu’il en soit, il n’y a pas de réponse unique. À vous de vous adapter au contexte particulier de votre analyse.

enfants[duree_observation < 0, date_entretien := date_entretien %m+% months(1)]
enfants[, duree_observation := time_length(interval(date_naissance, date_entretien), unit = "months")]

Regardons maintenant comment les âges au décès ont été collectés.

freq(enfants$age_deces)

Les âges au décès sont ici exprimés en mois révolus. Les décès à un mois révolu correspondent à des décès entre 1 et 2 mois exacts. Par ailleurs, les durées d’observation que nous avons calculées avec time_length sont des durées exactes, c’est-à-dire avec la partie décimale. Pour une analyse de survie, on ne peut mélanger des durées exactes et des durées révolues. Trois approches peuvent être envisagées :

  1. faire l’analyse en mois révolus, auquel cas on ne gardera que la partie entière des durées d’observations avec la fonction trunc ;
  2. considérer qu’un âge au décès de 3 mois révolus correspond en moyenne à 3,5 mois exacts et donc ajouter 0,5 à tous les âges révolus ;
  3. imputer un âge au décès exact en distribuant aléatoirement les décès à 3 mois révolus entre 3 et 4 mois exacts, autrement dit en ajoutant aléatoirement une partie décimale aux âges révolus.

Nous allons ici adopter la troisième approche en considérant que les décès se répartissent de manière uniforme au sein d’un même mois. Nous aurons donc recours à la fonction runif qui permets de générer des valeurs aléatoires entre 0 et 1 selon une distribustion uniforme.

enfants[, age_deces_impute := age_deces + runif(.N)]

Pour définir notre objet de survie, il nous faudra deux variables. Une première, temporelle, indiquant la durée à laquelle survient l’évènement étudié (ici le décès) pour ceux ayant vécu l’évènement et la durée d’observation pour ceux n’ayant pas vécu l’évènement (censure à droite). Par ailleurs, une seconde variable indiquant si les individus ont vécu l’évènement (0 pour non, 1 pour oui). Or, ici, la variable survie est codée 0 pour les décès et 1 pour ceux ayant survécu. Pour plus de détails, voir l’aide de la fonction Surv.

enfants[, deces := 0]
enfants[survie == 0, deces := 1]
var_label(enfants$deces) <- "Est décédé ?"
val_labels(enfants$deces) <- c(non = 0, oui = 1)

enfants[, time := duree_observation]
enfants[deces == 1, time := age_deces_impute]

Occupons-nous maintenant des variables explicatives que nous allons inclure dans l’analyse. Tout d’abord, ajoutons à la table enfants les variables nécessaires des tables femmes et menages. Notons qu’il nous faudra importer id_menage de la table femmes pour pouvoir fusionner ensuite la table enfants avec la table menages. Par ailleurs, pour éviter une confusion sur la variable date_naissance, nous renommons à la volée cette variable de la table femmes en date_naissance_mere.

enfants <- merge(
  enfants,
  femmes[, .(
    id_femme, id_menage, milieu, educ, 
    date_naissance_mere = date_naissance, nb_enf_ideal
  )],
  by = "id_femme",
  all.x = TRUE
)
enfants <- merge(
  enfants,
  menages[, .(id_menage, structure, richesse)],
  by = "id_menage",
  all.x = TRUE
)

Les variables catégorielles sont pour l’heure sous formes de vecteurs labellisés. Or, dans un modèle, il est impératif de les convertir en facteurs pour qu’elles soient bien traitées comme des variables catégorielles (autrement elles seraient traitées comme des variables continues). On aura donc recours à la fonction to_factor de l’extension labelled.

enfants[, sexe := to_factor(sexe)]
enfants[, richesse := to_factor(richesse)]

Regardons plus attentivement, la variable structure.

freq(enfants$structure)

Tout d’abord, la modalité pas d’adulte n’est pas représentée dans l’échantillon. On aura donc recours à l’argument drop_unused_labels pour ne pas conserver cette modalité. Par ailleurs, nous considérons que la situation familiale à partir de laquelle nous voudrons comparer les autres dans notre modèle, donc celle qui doit être considérée comme la modalité de référence, est celle du ménage nucléaire. Cette modalité (deux adultes de sexe opposé) n’étant pas la première, nous aurons recours à la fonction relevel.

enfants[, structure := to_factor(structure, drop_unused_labels = TRUE)]
enfants[, structure := relevel(structure, "deux adultes de sexe opposé")]

Regardons la variable educ.

freq(enfants$educ)

La modalité supérieur est peu représentée dans notre échantillon. Nous allons la fusionner avec la modalité secondaire (voir la section Regrouper les modalités d’une variable du chapitre Recodage).

enfants[, educ2 := educ]
enfants[educ == 3, educ2 := 2]
val_label(enfants$educ2, 2) <- "secondaire ou plus"
val_label(enfants$educ2, 3) <- NULL
enfants[, educ2 := to_factor(educ2)]
freq(enfants$educ2)

Calculons maintenant l’âge de la mère à la naissance de l’enfant (voir le chapitre Calculer un âge) et découpons le en groupes d’âges (voir la section Découper une variable numérique en classes du chapitre Recodage).

enfants[, age_mere_naissance := time_length(
  interval(date_naissance_mere, date_naissance), 
  unit = "years"
  )]

enfants$gpage_mere_naissance <- cut(
  enfants$age_mere_naissance, 
  include.lowest = TRUE, right = FALSE,
  breaks=c(13, 20, 30, 50)
)
levels(enfants$gpage_mere_naissance) <- c(
  "19 ou moins", "20-29", "30 et plus"
)
enfants$gpage_mere_naissance <- relevel(enfants$gpage_mere_naissance, "20-29")
freq(enfants$gpage_mere_naissance)

Reste à calculer si le rang de naissance de l’enfant est supérieur au nombre idéal d’enfants tel que défini par la mère. On aura recours à la fonction rank appliquée par groupe (ici calculé séparément pour chaque mère). L’argument ties.method permet d’indiquer comment gérer les égalités (ici les naissances multiples, e.g. les jumeaux). Comme nous voulons comparer le rang de l’enfant au nombre idéal d’enfants, nous allons retenir la méthode "max" pour obtenir, dans le cas présent, le nombre total d’enfants déjà nés1. Avant de calculer un rang, il est impératif de trier préalablement le tableau (voir le chapitre Tris).

setorder(enfants, id_femme, date_naissance)
enfants[, rang := rank(date_naissance, ties.method = "max"), by = id_femme]
enfants[, rang_apres_ideal := "non"]
# note: unclass() requis en raison d'un bug non corrigé dans haven empéchant de comparer haven_labelled_spss et integer
enfants[rang > unclass(nb_enf_ideal), rang_apres_ideal := "oui"]
enfants[, rang_apres_ideal := factor(rang_apres_ideal)]
enfants[, rang_apres_ideal := relevel(rang_apres_ideal, "non")]

Préparation des données avec dplyr

Tout d’abord, regardons sous quel format elles sont stockées.

data(fecondite)
class(menages)
[1] "tbl_df"     "tbl"        "data.frame"
describe(menages)
[1814 obs. x 5 variables] tbl_df tbl data.frame

$id_menage: Identifiant du ménage
numeric: 1 2 3 4 5 6 7 8 9 10 ...
min: 1 - max: 1814 - NAs: 0 (0%) - 1814 unique values

$taille: Taille du ménage (nombre de membres)
numeric: 7 3 6 5 7 6 15 6 5 19 ...
min: 1 - max: 31 - NAs: 0 (0%) - 30 unique values

$sexe_chef: Sexe du chef de ménage
labelled double: 2 1 1 1 1 2 2 2 1 1 ...
min: 1 - max: 2 - NAs: 0 (0%) - 2 unique values
2 value labels: [1] homme [2] femme

$structure: Structure démographique du ménage
labelled double: 4 2 5 4 4 4 5 2 5 5 ...
min: 1 - max: 5 - NAs: 0 (0%) - 5 unique values
6 value labels: [0] pas d'adulte [1] un adulte [2] deux adultes de sexe opposé [3] deux adultes de même sexe [4] trois adultes ou plus avec lien de parenté [5] adultes sans lien de parenté

$richesse: Niveau de vie (quintiles)
labelled double: 1 2 2 1 1 3 2 5 4 3 ...
min: 1 - max: 5 - NAs: 0 (0%) - 5 unique values
5 value labels: [1] très pauvre [2] pauvre [3] moyen [4] riche [5] très riche

Les tableaux de données sont déjà au format tibble (c’est-à-dire sont de la classe tbl_df)2 et les variables catégorielles sont du type labelled (voir le chapitre sur les vecteurs labellisés). Ce format correspond au format de données si on les avait importées depuis SPSS avec l’extension haven (voir le chapitre sur l’import de données).

Nous allons charger en mémoire l’extension labelled pour la gestion des vecteurs labellisés en plus de dplyr.

library(dplyr)
library(labelled)

En premier lieu, il nous faut calculer la durée d’observation des enfants, à savoir le temps passé entre la date de naissance (variable du fichier enfants) et la date de passation de l’entretien (fournie par le tableau de données femmes). Pour récupérer des variables du fichier femmes dans le fichier enfants, nous allons procéder à une fusion de table (voir le chapitre dédié). Pour le calcul de la durée d’observation, nous allons utiliser le package lubridate (voir le chapitre calculer un âge et celui sur la gestion des dates). Nous effectuerons l’analyse en mois (puisque l’âge au décès est connu en mois). Dès lors, la durée d’observation sera calculée en mois.

ATTENTION : les étiquettes de valeurs sont le plus souvent perdus lors des fusions de tables avec dplyr. Pour les récupérer après fusion, nous allons conserver une version originale du tableau de données enfants et utiliser la fonction copy_labels_from de l’extension labelled.

enfants_original <- enfants

library(lubridate)
enfants <- enfants %>%
  left_join(
    femmes %>% select(id_femme, date_entretien),
    by = "id_femme"
  ) %>%
  copy_labels_from(enfants_original) %>%
  mutate(duree_observation = time_length(
    interval(date_naissance, date_entretien), 
    unit = "months"
  ))

ATTENTION : il y 11 enfants soi-disant nés après la date d’enquête ! Quelle que soit l’enquête, il est rare de ne pas observer d’incohérences. Dans le cas présent, il est fort possible que la date d’entretien puisse parfois être erronnée (par exemple si l’enquêteur a inscrit une date sur le questionnaire papier le jour du recensement du ménage mais n’ai pu effectué le questionnaire individuel que plus tard). Nous décidons ici de procéder à une correction en ajoutant un mois aux dates d’entretien problématiques. D’autres approches auraient pu être envisagées, comme par exemple exclure ces observations problématiques. Cependant, cela aurait impacté le calcul du range de naissance pour les autres enfants issus de la même mère. Quoiqu’il en soit, il n’y a pas de réponse unique. À vous de vous adapter au contexte particulier de votre analyse.

enfants$date_entretien[enfants$duree_observation < 0] <-
  enfants$date_entretien[enfants$duree_observation < 0] %m+% months(1)
enfants <- enfants %>%
  mutate(duree_observation = time_length(
    interval(date_naissance, date_entretien), 
    unit = "months"
  ))

Regardons maintenant comment les âges au décès ont été collectés.

freq(enfants$age_deces)

Les âges au décès sont ici exprimés en mois révolus. Les décès à un mois révolu correspondent à des décès entre 1 et 2 mois exacts. Par ailleurs, les durées d’observation que nous avons calculées avec time_length sont des durées exactes, c’est-à-dire avec la partie décimale. Pour une analyse de survie, on ne peut mélanger des durées exactes et des durées révolues. Trois approches peuvent être envisagées :

  1. faire l’analyse en mois révolus, auquel cas on ne gardera que la partie entière des durées d’observations avec la fonction trunc ;
  2. considérer qu’un âge au décès de 3 mois révolus correspond en moyenne à 3,5 mois exacts et donc ajouter 0,5 à tous les âges révolus ;
  3. imputer un âge au décès exact en distribuant aléatoirement les décès à 3 mois révolus entre 3 et 4 mois exacts, autrement dit en ajoutant aléatoirement une partie décimale aux âges révolus.

Nous allons ici adopter la troisième approche en considérant que les décès se répartissent de manière uniforme au sein d’un même mois. Nous aurons donc recours à la fonction runif qui permets de générer des valeurs aléatoires entre 0 et 1 selon une distribustion uniforme.

enfants <- enfants %>%
  dplyr::mutate(age_deces_impute = age_deces + runif(n()))

Pour définir notre objet de survie, il nous faudra deux variables. Une première, temporelle, indiquant la durée à laquelle survient l’évènement étudié (ici le décès) pour ceux ayant vécu l’évènement et la durée d’observation pour ceux n’ayant pas vécu l’évènement (censure à droite). Par ailleurs, une seconde variable indiquant si les individus ont vécu l’évènement (0 pour non, 1 pour oui). Or, ici, la variable survie est codée 0 pour les décès et 1 pour ceux ayant survécu. Pour plus de détails, voir l’aide de la fonction Surv.

enfants <- enfants %>%
  mutate(deces = if_else(survie == 0, 1, 0)) %>%
  set_variable_labels(deces = "Est décédé ?") %>%
  set_value_labels(deces = c(non = 0, oui = 1)) %>%
  mutate(time = if_else(deces == 1, age_deces_impute, duree_observation))

Occupons-nous maintenant des variables explicatives que nous allons inclure dans l’analyse. Tout d’abord, ajoutons à la table enfants les variables nécessaires des tables femmes et menages. Notons qu’il nous faudra importer id_menage de la table femmes pour pouvoir fusionner ensuite la table enfants avec la table menages. Par ailleurs, pour éviter une confusion sur la variable date_naissance, nous renommons à la volée cette variable de la table femmes en date_naissance_mere.

enfants <- enfants %>%
  left_join(
    select(femmes,
      id_femme, id_menage, milieu, educ, 
      date_naissance_mere = date_naissance, nb_enf_ideal
    ),
    by = "id_femme"
  ) %>%
  left_join(
    select(menages, id_menage, structure, richesse),
    by = "id_menage"
  ) %>%
  copy_labels_from(enfants_original) %>%
  copy_labels_from(femmes) %>%
  copy_labels_from(menages)

Les variables catégorielles sont pour l’heure sous formes de vecteurs labellisés. Or, dans un modèle, il est impératif de les convertir en facteurs pour qu’elles soient bien traitées comme des variables catégorielles (autrement elles seraient traitées comme des variables continues). On aura donc recours à la fonction to_factor de l’extension labelled.

enfants <- enfants %>%
  mutate(sexe = to_factor(sexe), richesse = to_factor(richesse))

Regardons plus attentivement, la variable structure.

freq(enfants$structure)

Tout d’abord, la modalité pas d’adulte n’est pas représentée dans l’échantillon. On aura donc recours à l’argument drop_unused_labels pour ne pas conserver cette modalité. Par ailleurs, nous considérons que la situation familiale à partir de laquelle nous voudrons comparer les autres dans notre modèle, donc celle qui doit être considérée comme la modalité de référence, est celle du ménage nucléaire. Cette modalité (deux adultes de sexe opposé) n’étant pas la première, nous aurons recours à la fonction relevel{data-pkg = “stats”}.

enfants <- enfants %>%
  mutate(structure = relevel(
    to_factor(structure, drop_unused_labels = TRUE),
    "deux adultes de sexe opposé"
  ))

Regardons la variable educ.

freq(enfants$educ)

La modalité supérieur est peu représentée dans notre échantillon. Nous allons la fusionner avec la modalité secondaire (voir la section Regrouper les modalités d’une variable du chapitre Recodage).

enfants <- enfants %>%
  mutate(educ2 = ifelse(educ == 3, 2, educ)) %>%
  set_value_labels(educ2 = c(
    aucun = 0,
    primaire = 1,
    "secondaire ou plus" = 2
  )) %>%
  mutate(educ2 = to_factor(educ2))
freq(enfants$educ2)

Calculons maintenant l’âge de la mère à la naissance de l’enfant (voir le chapitre Caluler un âge) et découpons le en groupes d’âges (voir la section Découper une variable numérique en classes du chapitre Recodage).

enfants <- enfants %>%
  mutate(
    age_mere_naissance = time_length(
      interval(date_naissance_mere, date_naissance), 
      unit = "years"
    ),
    gpage_mere_naissance = cut(
      age_mere_naissance, 
      include.lowest = TRUE, right = FALSE,
      breaks=c(13, 20, 30, 50)
    )
  )
  
levels(enfants$gpage_mere_naissance) <- c(
  "19 ou moins", "20-29", "30 et plus"
)
enfants$gpage_mere_naissance <- relevel(enfants$gpage_mere_naissance, "20-29")
freq(enfants$gpage_mere_naissance)

Reste à calculer si le rang de naissance de l’enfant est supérieur au nombre idéal d’enfants tel que défini par la mère. On aura recours à la fonction rank appliquée par groupe (ici calculé séparément pour chaque mère). L’argument ties.method permet d’indiquer comment gérer les égalités (ici les naissances multiples, e.g. les jumeaux). Comme nous voulons comparer le rang de l’enfant au nombre idéal d’enfants, nous allons retenir la méthode "max" pour obtenir, dans le cas présent, le nombre total d’enfants déjà nés3. Avant de calculer un rang, il est impératif de trier préalablement le tableau (voir le chapitre Tris).

enfants <- enfants %>%
  arrange(id_femme, date_naissance) %>%
  group_by(id_femme) %>%
  mutate(
    rang = rank(date_naissance, ties.method = "max"),
    rang_apres_ideal = ifelse(rang > as.integer(nb_enf_ideal), "oui", "non"),
    rang_apres_ideal = factor(rang_apres_ideal, levels = c("non", "oui"))
  )

Kaplan-Meier

La courbe de survie de Kaplan-Meier s’obtient avec la fonction survfit de l’extension survival.

library(survival)
km_global <- survfit(Surv(time, deces) ~ 1, data = enfants)
km_global
Call: survfit(formula = Surv(time, deces) ~ 1, data = enfants)

      n  events  median 0.95LCL 0.95UCL 
   1584     142      NA      NA      NA 

Pour la représenter, on pourra avoir recours à la fonction ggsurvplot de l’extension survminer.

library(survminer, quietly = TRUE)
ggsurvplot(km_global)
Courbe de survie de Kaplan-Meier

On peut facilement représenter à la place la courbe cumulée des évènements (l’inverse de la courbe de survie) et la table des effectifs en fonction du temps.

ggsurvplot(km_global, fun = "event", risk.table = TRUE, surv.scale = "percent")
Courbe cumulée des évènements et table des effectifs

Pour comparer deux groupes (ici les filles et les garçons), il suffit d’indiquer la variable de comparaison à survfit.

km_sexe <- survfit(Surv(time, deces) ~ sexe, data = enfants)
km_sexe
Call: survfit(formula = Surv(time, deces) ~ sexe, data = enfants)

                n events median 0.95LCL 0.95UCL
sexe=masculin 762     94     NA      NA      NA
sexe=féminin  822     48     NA      NA      NA

La fonction survdiff permets de calculer le test du logrank afin de comparer des courbes de survie. La mortalité infanto-juvénile diffère-t-elle significativement selon le sexe de l’enfant ?

survdiff(Surv(time, deces) ~ sexe, data = enfants)
Call:
survdiff(formula = Surv(time, deces) ~ sexe, data = enfants)

                N Observed Expected (O-E)^2/E (O-E)^2/V
sexe=masculin 762       94     66.2      11.6      21.8
sexe=féminin  822       48     75.8      10.2      21.8

 Chisq= 21.8  on 1 degrees of freedom, p= 3e-06 

Une fois encore, on aura recours à ggsurvplot pour représenter les courbes de survie.

ggsurvplot(km_sexe, conf.int = TRUE, risk.table = TRUE, pval = TRUE, data = enfants)
Warning: Vectorized input to `element_text()` is not officially supported.
Results may be unexpected or may change in future versions of ggplot2.
Courbes de Kaplan-Meier selon le sexe

Modèle de Cox

Un modèle de Cox se calcule aisément avec coxph{survival}.

mod1 <- coxph(
  Surv(time, deces) ~ sexe + milieu + richesse + 
  structure + educ2 + gpage_mere_naissance + rang_apres_ideal, 
  data = enfants
)
mod1
Call:
coxph(formula = Surv(time, deces) ~ sexe + milieu + richesse + 
    structure + educ2 + gpage_mere_naissance + rang_apres_ideal, 
    data = enfants)

                                                         coef
sexeféminin                                         -0.809568
milieu                                               0.656241
richessepauvre                                      -0.082223
richessemoyen                                        0.318645
richesseriche                                        0.353483
richessetrès riche                                   0.464590
structureun adulte                                  -0.150231
structuredeux adultes de même sexe                   0.604592
structuretrois adultes ou plus avec lien de parenté  0.049430
structureadultes sans lien de parenté               -0.131369
educ2primaire                                       -0.030251
educ2secondaire ou plus                             -0.203903
gpage_mere_naissance19 ou moins                     -0.310248
gpage_mere_naissance30 et plus                      -0.002586
rang_apres_idealoui                                  1.355106
                                                    exp(coef)
sexeféminin                                          0.445050
milieu                                               1.927533
richessepauvre                                       0.921066
richessemoyen                                        1.375263
richesseriche                                        1.424019
richessetrès riche                                   1.591361
structureun adulte                                   0.860509
structuredeux adultes de même sexe                   1.830506
structuretrois adultes ou plus avec lien de parenté  1.050672
structureadultes sans lien de parenté                0.876895
educ2primaire                                        0.970202
educ2secondaire ou plus                              0.815541
gpage_mere_naissance19 ou moins                      0.733265
gpage_mere_naissance30 et plus                       0.997417
rang_apres_idealoui                                  3.877173
                                                     se(coef)
sexeféminin                                          0.177806
milieu                                               0.269928
richessepauvre                                       0.250417
richessemoyen                                        0.247868
richesseriche                                        0.298425
richessetrès riche                                   0.428583
structureun adulte                                   0.600329
structuredeux adultes de même sexe                   0.376445
structuretrois adultes ou plus avec lien de parenté  0.196666
structureadultes sans lien de parenté                0.305478
educ2primaire                                        0.205751
educ2secondaire ou plus                              0.366889
gpage_mere_naissance19 ou moins                      0.268062
gpage_mere_naissance30 et plus                       0.191557
rang_apres_idealoui                                  0.602401
                                                         z
sexeféminin                                         -4.553
milieu                                               2.431
richessepauvre                                      -0.328
richessemoyen                                        1.286
richesseriche                                        1.184
richessetrès riche                                   1.084
structureun adulte                                  -0.250
structuredeux adultes de même sexe                   1.606
structuretrois adultes ou plus avec lien de parenté  0.251
structureadultes sans lien de parenté               -0.430
educ2primaire                                       -0.147
educ2secondaire ou plus                             -0.556
gpage_mere_naissance19 ou moins                     -1.157
gpage_mere_naissance30 et plus                      -0.014
rang_apres_idealoui                                  2.250
                                                           p
sexeféminin                                         5.29e-06
milieu                                                0.0151
richessepauvre                                        0.7427
richessemoyen                                         0.1986
richesseriche                                         0.2362
richessetrès riche                                    0.2784
structureun adulte                                    0.8024
structuredeux adultes de même sexe                    0.1083
structuretrois adultes ou plus avec lien de parenté   0.8016
structureadultes sans lien de parenté                 0.6672
educ2primaire                                         0.8831
educ2secondaire ou plus                               0.5784
gpage_mere_naissance19 ou moins                       0.2471
gpage_mere_naissance30 et plus                        0.9892
rang_apres_idealoui                                   0.0245

Likelihood ratio test=38.16  on 15 df, p=0.0008546
n= 1584, number of events= 142 

De nombreuses variables ne sont pas significatives. Voyons si nous pouvons, avec la fonction step, améliorer notre modèle par minimisation de l’AIC ou Akaike Information Criterion (voir la section Sélection de modèles du chapitre sur la Régression logistique).

mod2 <- step(mod1)
Start:  AIC=2027.07
Surv(time, deces) ~ sexe + milieu + richesse + structure + educ2 + 
    gpage_mere_naissance + rang_apres_ideal

                       Df    AIC
- structure             4 2022.0
- richesse              4 2022.7
- educ2                 2 2023.4
- gpage_mere_naissance  2 2024.6
<none>                    2027.1
- rang_apres_ideal      1 2028.6
- milieu                1 2031.3
- sexe                  1 2047.1

Step:  AIC=2022.01
Surv(time, deces) ~ sexe + milieu + richesse + educ2 + gpage_mere_naissance + 
    rang_apres_ideal

                       Df    AIC
- richesse              4 2017.0
- educ2                 2 2018.2
- gpage_mere_naissance  2 2019.5
<none>                    2022.0
- rang_apres_ideal      1 2023.4
- milieu                1 2025.6
- sexe                  1 2042.2

Step:  AIC=2017
Surv(time, deces) ~ sexe + milieu + educ2 + gpage_mere_naissance + 
    rang_apres_ideal

                       Df    AIC
- educ2                 2 2013.3
- gpage_mere_naissance  2 2014.8
<none>                    2017.0
- rang_apres_ideal      1 2018.0
- milieu                1 2018.8
- sexe                  1 2037.6

Step:  AIC=2013.28
Surv(time, deces) ~ sexe + milieu + gpage_mere_naissance + rang_apres_ideal

                       Df    AIC
- gpage_mere_naissance  2 2011.2
<none>                    2013.3
- rang_apres_ideal      1 2014.3
- milieu                1 2015.7
- sexe                  1 2033.8

Step:  AIC=2011.17
Surv(time, deces) ~ sexe + milieu + rang_apres_ideal

                   Df    AIC
<none>                2011.2
- rang_apres_ideal  1 2012.3
- milieu            1 2013.9
- sexe              1 2031.6

On peut obtenir facilement les coefficients du modèle avec l’excellente fonction tidy de l’extension broom. Ne pas oublier de préciser exponentiate = TRUE. En effet, dans le cas d’un modèle de Cox, l’exponentiel des coefficients corresponds au ratio des risques instantannés ou hazard ratio (HR) en anglais.

library(broom, quietly = TRUE)
tidy(mod2, exponentiate = TRUE)

Pour représenter ces rapports de risque, on peut ici encore avoir recours à la fonction ggcoef de l’extension GGally.

library(GGally, quietly = TRUE)
Registered S3 method overwritten by 'GGally':
  method from   
  +.gg   ggplot2
ggcoef(mod2, exponentiate = TRUE)
Coefficients du modèle avec ggcoef

L’extension survminer fournit également une fonction ggforest qui permet de représenter de manière plus esthétique et complète les coefficients d’un modèle de Cox.

ggforest(mod2)
Coefficients du modèle avec ggforest

Vérification de la validité du modèle

Un modèle de Cox n’est valable que sous l’hypothèse de la proportionnalité des risques relatifs. Selon cette hypothèse les résidus de Schoenfeld ne dépendent pas du temps. Cette hypothèse peut être testée avec la fonction cox.zph.

test <- cox.zph(mod2)
test
                 chisq df    p
sexe             0.505  1 0.48
milieu           0.136  1 0.71
rang_apres_ideal 0.163  1 0.69
GLOBAL           0.805  3 0.85

Une valeur de p inférieure à 5 % indique que l’hypothèse n’est pas vérifiée. Il apparaît que p est supérieur à 5 % globalement et pour chaque variable prise individuellement. Notre modèle est donc valide.

Il est possible de représenter la distribution des résidus de Schoenfeld à l’aide de ggcoxzph de l’extension survminer, afin de voir si leur répartition change au cours du temps.

ggcoxzph(test)
Warning in regularize.values(x, y, ties, missing(ties),
na.rm = na.rm): collapsing to unique 'x' values
Résidus de Schoenfeld

Données pondérées

Si vous utilisez des données pondérées avec un plan d’échantillonnage complexe (voir le chapitre dédié), vous pouvez utilisez les fonctions suivantes de l’extension survey :

  • svykm pour estimer une courbe de survie de Kaplan-Meier ;
  • svycoxph pour un modèle de Cox.

Dans les deux cas, pensez à ajouter l’option se = TRUE pour que les erreurs standards soient calculées (et que les intervalles de confiance puissent être générés).


  1. Ici, pour plus de simplicité, nous n’avons pas pris en compte les décès éventuels des enfants de rang inférieur avant la naissance considérée.

  2. Si cela n’avait pas été le cas, nous aurions eu recours à la fonction tbl_df.

  3. Ici, pour plus de simplicité, nous n’avons pas pris en compte les décès éventuels des enfants de rang inférieur avant la naissance considérée.

Analyse de séquences

La version originale de ce chapitre est une reprise, avec l’aimable autorisation de son auteur, d’un article de Nicolas Robette intitulé L’analyse de séquences : une introduction avec le logiciel R et le package TraMineR et publié sur le blog Quanti (http://quanti.hypotheses.org/686/).

Depuis les années 1980, l’étude quantitative des trajectoires biographiques (life course analysis) a pris une ampleur considérable dans le champ des sciences sociales. Les collectes de données micro-individuelles longitudinales se sont développées, principalement sous la forme de panels ou d’enquêtes rétrospectives. Parallèlement à cette multiplication des données disponibles, la méthodologie statistique a connu de profondes évolutions. L’analyse des biographies (event history analysis) — qui ajoute une dimension diachronique aux modèles économétriques mainstream — s’est rapidement imposée comme l’approche dominante : il s’agit de modéliser la durée des situations ou le risque d’occurrence des événements.

L’analyse de séquences

Cependant, ces dernières années ont vu la diffusion d’un large corpus de méthodes descriptives d’analyse de séquences, au sein desquelles l’appariement optimal (optimal matching) occupe une place centrale1. L’objectif principal de ces méthodes est d’identifier — dans la diversité d’un corpus de séquences constituées de séries d’états successifs — les régularités, les ressemblances, puis le plus souvent de construire des typologies de « séquences-types ». L’analyse de séquences constitue donc un moyen de décrire mais aussi de mieux comprendre le déroulement de divers processus.

La majeure partie des applications de l’analyse de séquences traite de trajectoires biographiques ou de carrières professionnelles. Dans ces cas, chaque trajectoire ou chaque carrière est décrite par une séquence, autrement dit par une suite chronologiquement ordonnée de « moments » élémentaires, chaque moment correspondant à un « état » déterminé de la trajectoire (par exemple, pour les carrières professionnelles : être en emploi, au chômage ou en inactivité). Mais on peut bien sûr imaginer des types de séquences plus originaux : Andrew Abbott2, le sociologue américain qui a introduit l’optimal matching dans les sciences scientifiques ou des séquences de pas de danses traditionnelles.

En France, les premiers travaux utilisant l’appariement optimal sont ceux de Claire Lemercier3 sur les carrières des membres des institutions consulaires parisiennes au xixe siècle (Lemercier, 2005), et de Laurent Lesnard4 sur les emplois du temps (Lesnard, 2008). Mais dès les années 1980, les chercheurs du Céreq construisaient des typologies de trajectoires d’insertion à l’aide des méthodes d’analyse des données « à la française » (analyse des correspondances, etc.)5. Au final, on dénombre maintenant plus d’une centaine d’articles de sciences sociales contenant ou discutant des techniques empruntées à l’analyse de séquences.

Pour une présentation des différentes méthodes d’analyse de séquences disponibles et de leur mise en oeuvre pratique, il existe un petit manuel en français, publié en 2011 dernière aux éditions du Ceped (collection « Les clefs pour »6) et disponible en pdf7 (Robette, 2011). De plus, un article récemment publié dans le Bulletin de Méthodologie Sociologique compare de manière systématique les résultats obtenus par les principales méthodes d’analyse de séquences (Robette & Bry, 2012). La conclusion en est qu’avec des données empiriques aussi structurées que celles que l’on utilise en sciences sociales, l’approche est robuste, c’est-à-dire qu’un changement de méthode aura peu d’influence sur les principaux résultats. Cependant, l’article tente aussi de décrire les spécificités de chaque méthode et les différences marginales qu’elles font apparaître, afin de permettre aux chercheurs de mieux adapter leurs choix méthodologiques à leur question de recherche.

Afin d’illustrer la démarche de l’analyse de séquences, nous allons procéder ici à la description « pas à pas » d’un corpus de carrières professionnelles, issues de l’enquête Biographies et entourage (Ined, 2000)8. Et pour ce faire, on va utiliser le logiciel R, qui propose la solution actuellement la plus complète et la plus puissante en matière d’analyse de séquences. Les méthodes d’analyse de séquences par analyses factorielles ou de correspondances ne nécessitent pas de logiciel spécifique : tous les logiciels de statistiques généralistes peuvent être utilisés (SAS, SPSS, Stata, R, etc.). En revanche, il n’existe pas de fonctions pour l’appariement optimal dans SAS ou SPSS. Certains logiciels gratuits implémentent l’appariement optimal (comme Chesa9 ou TDA10) mais il faut alors recourir à d’autres programmes pour dérouler l’ensemble de l’analyse (classification, représentation graphique). Stata propose le module sq11, qui dispose d’un éventail de fonctions intéressantes. Mais c’est R et le package TraMineR12, développé par des collègues de l’Université de Genève (Gabadinho et al, 2011), qui fournit la solution la plus complète et la plus puissante à ce jour : on y trouve l’appariement optimal mais aussi d’autres algorithmes alternatifs, ainsi que de nombreuses fonctions de description des séquences et de représentation graphique.

Charger TraMineR et récupérer les données

Tout d’abord, à quoi ressemblent nos données ? On a reconstruit à partir de l’enquête les carrières de 1000 hommes. Pour chacune, on connaît la position professionnelle chaque année, de l’âge de 14 ans jusqu’à 50 ans. Cette position est codée de la manière suivante : les codes 1 à 6 correspondent aux groupes socioprofessionnels de la nomenclature des PCS de l’INSEE 13 (agriculteurs exploitants ; artisans, commerçants et chefs d’entreprise ; cadres et professions intellectuelles supérieures ; professions intermédiaires ; employés ; ouvriers) ; on y a ajouté « études » (code 7), « inactivité » (code 8) et « service militaire » (code 9). Le fichier de données comporte une ligne par individu et une colonne par année : la variable csp1 correspond à la position à 14 ans, la variable csp2 à la position à 15 ans, etc. Par ailleurs, les enquêtés étant tous nés entre 1930 et 1950, on ajoute à notre base une variable « génération » à trois modalités, prenant les valeurs suivantes : 1=“1930-1938” ; 2=“1939-1945” ; 3=“1946-1950”. Au final, la base est constituée de 500 lignes et de 37 + 1 = 38 colonnes et se présente sous la forme d’un fichier texte au format csv (téléchargeable à http://larmarange.github.io/analyse-R/data/trajpro.csv).

Une fois R ouvert, on commence par installer les extensions nécessaires à ce programme (opération à ne réaliser que lors de leur première utilisation) et par les charger en mémoire. L’extension TraMineR propose de nombreuses fonctions pour l’analyse de séquences. L’extension cluster comprend un certain nombre de méthodes de classification automatique13.

library(TraMineR)
library(cluster)

On importe ensuite les données, on recode la variable « génération » pour lui donner des étiquettes plus explicites. On jette également un coup d’oeil à la structure du tableau de données :


-- Column specification ------------------------------------
cols(
  .default = col_double()
)
i Use `spec()` for the full column specifications.
donnees <- read.csv("http://larmarange.github.io/analyse-R/data/trajpro.csv", header = T)
donnees$generation <- factor(donnees$generation, labels = c("1930-38", "1939-45", "1946-50"))
str(donnees)
tibble [1,000 x 38] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
 $ csp1      : num [1:1000] 1 7 6 7 7 6 7 7 7 6 ...
 $ csp2      : num [1:1000] 1 7 6 7 7 6 7 7 6 6 ...
 $ csp3      : num [1:1000] 1 7 6 6 7 6 7 7 6 6 ...
 $ csp4      : num [1:1000] 1 7 6 6 7 6 7 7 6 6 ...
 $ csp5      : num [1:1000] 1 7 6 6 7 6 7 7 6 6 ...
 $ csp6      : num [1:1000] 1 7 6 6 7 6 9 7 6 6 ...
 $ csp7      : num [1:1000] 6 9 6 6 7 6 9 7 9 6 ...
 $ csp8      : num [1:1000] 6 9 9 6 7 6 9 7 4 6 ...
 $ csp9      : num [1:1000] 6 6 9 6 7 6 9 3 4 9 ...
 $ csp10     : num [1:1000] 6 6 9 6 7 6 4 3 4 9 ...
 $ csp11     : num [1:1000] 6 6 6 6 3 6 4 3 4 6 ...
 $ csp12     : num [1:1000] 6 6 6 6 3 6 4 3 4 6 ...
 $ csp13     : num [1:1000] 6 6 6 6 3 6 4 3 4 6 ...
 $ csp14     : num [1:1000] 6 4 6 6 3 6 4 3 4 6 ...
 $ csp15     : num [1:1000] 6 4 6 6 3 6 4 3 4 6 ...
 $ csp16     : num [1:1000] 6 4 6 6 3 6 6 3 4 6 ...
 $ csp17     : num [1:1000] 6 4 6 6 3 6 6 3 4 6 ...
 $ csp18     : num [1:1000] 6 4 6 6 3 6 6 3 4 6 ...
 $ csp19     : num [1:1000] 6 4 6 6 3 6 6 3 4 6 ...
 $ csp20     : num [1:1000] 6 4 6 6 3 6 6 3 4 6 ...
 $ csp21     : num [1:1000] 6 4 6 6 6 6 6 3 4 6 ...
 $ csp22     : num [1:1000] 6 4 6 6 6 6 6 3 4 4 ...
 $ csp23     : num [1:1000] 6 4 6 6 6 6 6 3 4 4 ...
 $ csp24     : num [1:1000] 6 6 6 6 5 6 6 3 4 4 ...
 $ csp25     : num [1:1000] 6 6 6 6 5 6 6 3 4 4 ...
 $ csp26     : num [1:1000] 6 6 6 6 5 6 6 3 4 4 ...
 $ csp27     : num [1:1000] 6 6 6 6 5 6 6 3 4 4 ...
 $ csp28     : num [1:1000] 6 6 6 6 5 6 6 3 4 4 ...
 $ csp29     : num [1:1000] 6 6 6 6 5 6 6 3 4 4 ...
 $ csp30     : num [1:1000] 4 6 6 6 5 6 6 3 4 4 ...
 $ csp31     : num [1:1000] 4 6 6 6 5 6 6 3 4 4 ...
 $ csp32     : num [1:1000] 4 6 6 6 5 6 6 3 4 4 ...
 $ csp33     : num [1:1000] 4 6 6 6 5 6 6 3 4 4 ...
 $ csp34     : num [1:1000] 4 6 6 6 5 6 6 3 4 4 ...
 $ csp35     : num [1:1000] 4 6 6 6 5 6 6 3 4 4 ...
 $ csp36     : num [1:1000] 4 6 6 6 5 6 6 3 4 4 ...
 $ csp37     : num [1:1000] 4 6 6 6 5 6 6 3 4 4 ...
 $ generation: Factor w/ 3 levels "1930-38","1939-45",..: 2 1 1 3 2 3 1 1 2 1 ...
 - attr(*, "spec")=
  .. cols(
  ..   csp1 = col_double(),
  ..   csp2 = col_double(),
  ..   csp3 = col_double(),
  ..   csp4 = col_double(),
  ..   csp5 = col_double(),
  ..   csp6 = col_double(),
  ..   csp7 = col_double(),
  ..   csp8 = col_double(),
  ..   csp9 = col_double(),
  ..   csp10 = col_double(),
  ..   csp11 = col_double(),
  ..   csp12 = col_double(),
  ..   csp13 = col_double(),
  ..   csp14 = col_double(),
  ..   csp15 = col_double(),
  ..   csp16 = col_double(),
  ..   csp17 = col_double(),
  ..   csp18 = col_double(),
  ..   csp19 = col_double(),
  ..   csp20 = col_double(),
  ..   csp21 = col_double(),
  ..   csp22 = col_double(),
  ..   csp23 = col_double(),
  ..   csp24 = col_double(),
  ..   csp25 = col_double(),
  ..   csp26 = col_double(),
  ..   csp27 = col_double(),
  ..   csp28 = col_double(),
  ..   csp29 = col_double(),
  ..   csp30 = col_double(),
  ..   csp31 = col_double(),
  ..   csp32 = col_double(),
  ..   csp33 = col_double(),
  ..   csp34 = col_double(),
  ..   csp35 = col_double(),
  ..   csp36 = col_double(),
  ..   csp37 = col_double(),
  ..   generation = col_double()
  .. )

On a bien 1000 observations et 38 variables. On définit maintenant des labels pour les différents états qui composent les séquences et on crée un objet « séquence » avec seqdef :

labels <- c("agric", "acce", "cadr", "pint", "empl", "ouvr", "etud", "inact", "smil")
seq <- seqdef(donnees[, 1:37], states = labels)
 [>] state coding:
       [alphabet]  [label]  [long label] 
     1  1           agric    agric
     2  2           acce     acce
     3  3           cadr     cadr
     4  4           pint     pint
     5  5           empl     empl
     6  6           ouvr     ouvr
     7  7           etud     etud
     8  8           inact    inact
     9  9           smil     smil
 [>] 1000 sequences in the data set
 [>] min/max sequence length: 37/37

Appariement optimal et classification

Ces étapes préalables achevées, on peut comparer les séquences en calculant les dissimilarités entre paires de séquences. On va ici utiliser la méthode la plus répandue, l’appariement optimal (optimal matching). Cette méthode consiste, pour chaque paire de séquences, à compter le nombre minimal de modifications (substitutions, suppressions, insertions) qu’il faut faire subir à l’une des séquences pour obtenir l’autre. On peut considérer que chaque modification est équivalente, mais il est aussi possible de prendre en compte le fait que les « distances » entre les différents états n’ont pas toutes la même « valeur » (par exemple, la distance sociale entre emploi à temps plein et chômage est plus grande qu’entre emploi à temps plein et emploi à temps partiel), en assignant aux différentes modifications des « coûts » distincts. Dans notre exemple, on va créer avec seqsubm une « matrice des coûts de substitution » dans laquelle tous les coûts sont constants et égaux à 214 :

couts <- seqsubm(seq, method = "CONSTANT", cval = 2)
 [>] creating 9x9 substitution-cost matrix using 2 as constant value

Ensuite, on calcule la matrice de distances entre les séquences (i.e contenant les « dissimilarités » entre les séquences) avec seqdist, avec un coût d’insertion/suppression (indel) que l’on fixe ici à 1 :

seq.om <- seqdist(seq, method = "OM", indel = 1, sm = couts)
 [>] 1000 sequences with 9 distinct states
 [>] checking 'sm' (size and triangle inequality)
 [>] 818 distinct  sequences 
 [>] min/max sequence lengths: 37/37
 [>] computing distances using the OM metric
 [>] elapsed time: 1.86 secs

Ce cas de figure où tous les coûts de substitution sont égaux à 2 et le coût indel égal à 1 correspond à un cas particulier d’optimal matching que l’on appelle la Longuest Common Subsequence ou LCS. Elle peut se calculer directement avec seqdist de la manière suivante :

seq.om <- seqdist(seq, method = "LCS")
 [>] 1000 sequences with 9 distinct states
 [>] creating a 'sm' with a substitution cost of 2
 [>] creating 9x9 substitution-cost matrix using 2 as constant value
 [>] 818 distinct  sequences 
 [>] min/max sequence lengths: 37/37
 [>] computing distances using the LCS metric
 [>] elapsed time: 1.85 secs

En l’absence d’hypothèses fortes sur les différents statuts auxquels correspond notre alphabet (données hiérarchisées, croisement de différentes dimensions…), nous vous recommandons d’utiliser prioritairement la métrique LCS pour calculer la distance entre les séquences.

On pourra trouver un exemple de matrice de coûts hiérarchisée dans le chapitre sur les trajectoires de soins.

Cette matrice des distances ou des dissimilarités entre séquences peut ensuite être utilisée pour une classification ascendante hiérarchique (CAH), qui permet de regrouper les séquences en un certain nombre de « classes » en fonction de leur proximité :

seq.dist <- hclust(as.dist(seq.om), method = "ward.D2")

Avec la fonction plot, il est possible de tracer l’arbre de la classification (dendrogramme).

plot(as.dendrogram(seq.dist), leaflab = "none")
Dendrogramme de la classification des séquences

De même, on peut représenter les sauts d’inertie.

plot(sort(seq.dist$height, decreasing = TRUE)[1:20], type = "s", xlab = "nb de classes", ylab = "inertie")
Sauts d’inertie de la classification des séquences

L’observation, sur ce dendogramme ou sur la courbe des sauts d’inertie, des sauts d’inertie des dernières étapes de la classification peut servir de guide pour déterminer le nombre de classes que l’on va retenir pour la suite des analyses. Une première inflexion dans la courbe des sauts d’inertie apparaît au niveau d’une partition en 5 classes. On voit aussi une seconde inflexion assez nette à 7 classes. Mais il faut garder en tête le fait que ces outils ne sont que des guides, le choix devant avant tout se faire après différents essais, en fonction de l’intérêt des résultats par rapport à la question de recherche et en arbitrant entre exhaustivité et parcimonie.

On fait ici le choix d’une partition en 5 classes :

nbcl <- 5
seq.part <- cutree(seq.dist, nbcl)
seq.part <- factor(seq.part, labels = paste("classe", 1:nbcl, sep = "."))

Représentations graphiques

Pour se faire une première idée de la nature des classes de la typologie, il existe un certain nombre de représentations graphiques. Les chronogrammes (state distribution plots) présentent une série de coupes transversales : pour chaque âge, on a les proportions d’individus de la classe dans les différentes situations (agriculteur, étudiant, etc.). Ce graphique s’obtient avec seqdplot :

seqdplot(seq, group = seq.part, xtlab = 14:50, border = NA)
Chronogrammes

Chacune des classes semble caractérisée par un groupe professionnel principal : profession intermédiaire pour la classe 1, ouvrier pour la 2, employé pour la 3, cadre pour la 4 et indépendant pour la 5. Cependant, on aperçoit aussi des « couches » d’autres couleurs, indiquant que l’ensemble des carrières ne sont probablement pas stables.

Les « tapis » (index plots), obtenus avec seqIplot, permettent de mieux visualiser la dimension individuelle des séquences. Chaque segment horizontal représente une séquence, découpée en sous-segments correspondant aux aux différents états successifs qui composent la séquence.

seqIplot(seq, group = seq.part, xtlab = 14:50, space = 0, border = NA, yaxis = FALSE)
Tapis des séquences triés

Il est possible de trier les séquences pour rendre les tapis plus lisibles (on trie ici par multidimensional scaling à l’aide de la fonction cmdscale).

ordre <- cmdscale(as.dist(seq.om), k = 1)
seqIplot(seq, group = seq.part, sortv = ordre, xtlab = 14:50, space = 0, border = NA, yaxis = FALSE)
Tapis des séquences triés par multidimensional scaling

On voit mieux apparaître ainsi l’hétérogénéité de certaines classes. Les classes 1, 3 et 4, par exemple, semblent regrouper des carrières relativement stables (respectivement de professions intermédiaires, d’employés et de cadres) et des carrières plus « mobiles » commencées comme ouvrier (classes 1 et 3, en orange) ou comme profession intermédiaire (classe 4, en rouge). De même, la majorité des membres de la dernière classe commencent leur carrière dans un groupe professionnel distinct de celui qu’ils occuperont par la suite (indépendants). Ces distinctions apparaissent d’ailleurs si on relance le programme avec un nombre plus élevé de classes (en remplaçant le 5 de la ligne nbcl <- 5 par 7, seconde inflexion de la courbe des sauts d’inertie, et en exécutant de nouveau le programme à partir de cette ligne) : les stables et les mobiles se trouvent alors dans des classes distinctes.

Le package JLutils, disponible sur GitHub, propose une fonction seq_heatmap permettant de représenter le tapis de l’ensemble des séquences selon l’ordre du dendrogramme.

Pour installer JLutils, on aura recours au package devtools et à sa fonction install_github :

library(devtools)
install_github("larmarange/JLutils")

On peut ensuite générer le graphique ainsi :

library(JLutils)
seq_heatmap(seq, seq.dist, labCol = 14:50)
Tapis des séquences trié selon le dendrogramme

Il est possible de reproduire un tapis de séquence avec ggplot2. Outre le fait que cela fournit plus d’options de personnalisation du graphique, cela permets également à ce que la hauteur de chaque classe sur le graphique soit proportionnelle aux nombre d’invidus.

En premier lieu, on a va ajouter à notre fichier de données des identifiants individuels, la typologie crée et l’ordre obtenu par multidimensional scaling.

donnees$id <- row.names(donnees)
donnees$classe <- seq.part
donnees$ordre <- rank(ordre, ties.method = "random")

Ensuite, il est impératif que nos données soient dans un format long et tidy, c’est-à-dire avec une ligne par individu et par pas de temps. Pour cela on aura recours à la fonction gather (voir le chapitre dédié).

library(tidyr)
long <- donnees %>% gather(csp1:csp37, key = annee, value = csp)

On va mettre en forme la variable csp sous forme de facteur, récupérer l’année grace à la fonction str_sub de l’extension stringr (voir le chapitre sur la manipulation de texte) et recalculer l’âge.

long$csp <- factor(long$csp, labels = c("agriculteur", "art./com./chefs", "cadres", "prof. int.", "employés", "ouvriers", "étudiants", "inactifs", "serv. militaire"))
library(stringr)
long$annee <- as.integer(str_sub(long$annee, 4))
long$age <- long$annee + 13

Il n’y a plus qu’à faire notre graphique grace à geom_raster qui permet de colorier chaque pixel. Techniquement, pour un tapis de séquence, il s’agit de représenter le temps sur l’axe horizontal et les individus sur l’axe vertical. Petite astuce : plutôt que d’utiliser id pour l’axe vertical, nous utilisons ordre afin de trier les observations. Par ailleurs, il est impératif de transformer au passage ordre en facteur afin que ggplot2 puisse recalculer proprement et séparément les axes pour chaque facette15, à condition de ne pas oublier l’option scales = "free_y" dans l’appel à facet_grid. Les autres commandes ont surtout pour vocation d’améliorer le rendu du graphique (voir le chapitre dédié à ggplot2).

library(ggplot2)
ggplot(long) +
  aes(x = age, y = factor(ordre), fill = csp) +
  geom_raster() +
  ylab("") +
  scale_y_discrete(label = NULL) +
  theme_bw() +
  theme(legend.position = "bottom") +
  scale_fill_brewer(palette = "Set3") +
  facet_grid(classe ~ ., scales = "free_y", space = "free_y") +
  scale_x_continuous(limits = c(14, 50), breaks = c(14, 20, 25, 30, 35, 40, 45, 50), expand = c(0, 0))
Warning: Removed 2000 rows containing missing values
(geom_raster).

La distance des séquences d’une classe au centre de cette classe, obtenue avec disscenter, permet de mesurer plus précisément l’homogénéité des classes. Nous utilisons ici aggregate pour calculer la moyenne par classe :

aggregate(disscenter(as.dist(seq.om), group = seq.part), list(seq.part), mean)

Cela nous confirme que les classes 1, 3 et 5 sont nettement plus hétérogènes que les autres, alors que la classe 2 est la plus homogène.

D’autres représentations graphiques existent pour poursuivre l’examen de la typologie. On peut visualiser les 10 séquences les plus fréquentes de chaque classe avec seqfplot.

seqfplot(seq, group = seq.part)
Séquences les plus fréquentes de chaque classe

On peut aussi visualiser avec seqmsplot l’état modal (celui qui correspond au plus grand nombre de séquences de la classe) à chaque âge.

seqmsplot(seq, group = seq.part, xtlab = 14:50, main = "classe")
Statut modal à chaque âge

On peut également représenter avec seqmtplot les durées moyennes passées dans les différents états.

seqmtplot(seq, group = seq.part)
Durée moyenne dans chaque statut

La fonction seqrplot cherche à identifier des séquences représentatives de chaque classe. Plusieurs méthodes sont proposées (voir seqrep). La méthode dist cherche à identifier des séquences centrales à chaque classe, c’est-à-dire situées à proximité du centre de la classe. Selon l’hétérogénéité de la classe, plusieurs séquences représentatives peuvent être renvoyées. ATTENTION : il faut être prudent dans l’interprétation de ces séquences centrales de la classe dans la mesure où elles ne rendent pas toujours compte de ce qui se passe dans la classe et où elles peuvent induire en erreur quand la classe est assez hétérogène. Il faut donc les considérer tout en ayant en tête l’ensemble du tapis de séquence pour voir si elles sont effectivement de bonnes candidates.

seqrplot(seq, group = seq.part, dist.matrix = seq.om, criterion = "dist")
Séquences représentatives de chaque classe

Enfin, l’entropie transversale décrit l’évolution de l’homogénéité de la classe. Pour un âge donné, une entropie proche de 0 signifie que tous les individus de la classe (ou presque) sont dans la même situation. À l’inverse, l’entropie est de 1 si les individus sont dispersés dans toutes les situations. Ce type de graphique produit par seqHtplot peut être pratique pour localiser les moments de transition, l’insertion professionnelle ou une mobilité sociale ascendante.

seqHtplot(seq, group = seq.part, xtlab = 14:50)
Entropie transversale

Distribution de la typologie

On souhaite maintenant connaître la distribution de la typologie (en effectifs et en pourcentages) :

library(questionr)
freq(seq.part)

On poursuit ensuite la description des classes en croisant la typologie avec la variable generation :

cprop(table(seq.part, donnees$generation))
          
seq.part   1930-38 1939-45 1946-50 Ensemble
  classe.1  35.6    32.5    40.8    36.6   
  classe.2  19.7    18.3    17.0    18.3   
  classe.3   6.5    13.9    11.2    10.4   
  classe.4  31.8    29.2    27.9    29.6   
  classe.5   6.5     6.1     3.0     5.1   
  Total    100.0   100.0   100.0   100.0   
chisq.test(table(seq.part, donnees$generation))

    Pearson's Chi-squared test

data:  table(seq.part, donnees$generation)
X-squared = 18.518, df = 8, p-value = 0.01766

Le lien entre le fait d’avoir un certain type de carrières et la cohorte de naissance est significatif à un seuil de 15 %. On constate par exemple l’augmentation continue de la proportion de carrières de type « professions intermédiaires » (classe 1) et, entre les deux cohortes les plus anciennes, l’augmentation de la part des carrières de type « employés » (classe 3) et la baisse de la part des carrières de type « cadres » (classe 4).

Bien d’autres analyses sont envisageables : croiser la typologie avec d’autres variables (origine sociale, etc.), construire l’espace des carrières possibles, étudier les interactions entre trajectoires familiales et professionnelles, analyser la variance des dissimilarités entre séquences en fonction de plusieurs variables « explicatives16 »…

Mais l’exemple proposé est sans doute bien suffisant pour une première introduction !

Pour aller plus loin

En premier lieu, la lecture du manuel d’utilisation de TraMineR, intitulé Mining sequence data in R with the TraMineR package: A user’s guide et écrit par Alexis Gabadinho, Gilbert Ritschard, Matthias Studer et Nicolas S. Muller, est fortement conseillée. Ce manuel ne se contente pas de présenter l’extension, mais aborde également la théorie sous-jacente de l’analyse de séquences, les différents formats de données, les différences approches (séquences de statut ou séquences de transitions par exemple), etc.

Pour une initiation en français, on pourra se référer à l’ouvrage de Nicolas Robette Explorer et décrire les parcours de vie : les typologies de trajectoires sorti en 2011 aux éditions du Ceped.

L’extension WeightedCluster de Matthias Studer est un excellent complément à TraMineR. Il a également écrit un manuel de la librairie WeightedCluster : un guide pratique pour la création de typologies de trajectoires en sciences sociales avec R.

Enfin, l’extension TraMineRextras (https://cran.r-project.org/package=TraMineRextras) contient des fonctions complémentaires à TraMineR, plus ou moins en phase de test.

Bibliographie


  1. Pour une analyse des conditions sociales de la diffusion de l’analyse de séquences dans le champ des sciences sociales, voir Robette, 2012.

  2. http://home.uchicago.edu/~aabbott/

  3. http://lemercier.ouvaton.org/document.php?id=62

  4. http://laurent.lesnard.free.fr/article.php3?id_article=22

  5. Voir par exemple l’article d’Yvette Grelet (2002).

  6. http://www.ceped.org/?rubrique57

  7. http://nicolas.robette.free.fr/Docs/Robette2011_Manuel_TypoTraj.pdf

  8. Pour une analyse plus poussée de ces données, avec deux méthodes différentes, voir Robette & Thibault, 2008. Pour une présentation de l’enquête, voir Lelièvre & Vivier, 2001.

  9. http://home.fsw.vu.nl/ch.elzinga/

  10. http://steinhaus.stat.ruhr-uni-bochum.de/tda.html

  11. http://www.stata-journal.com/article.html?article=st0111

  12. http://mephisto.unige.ch/traminer/

  13. Pour une présentation plus détaillée, voir le chapitre sur la classification ascendante hiérarchique (CAH).

  14. Le fonctionnement de l’algorithme d’appariement optimal — et notamment le choix des coûts — est décrit dans le chapitre 9 du manuel de TraMineR (http://mephisto.unige.ch/pub/TraMineR/doc/TraMineR-Users-Guide.pdf).

  15. Essayez le même code mais avec y = ordre au lieu de y = factor(ordre) et vous comprendrez tout l’intérêt de cette astuce.

  16. L’articulation entre méthodes « descriptives » et méthodes « explicatives » est un prolongement possible de l’analyse de séquences. Cependant, l’analyse de séquences était envisagée par Abbott comme une alternative à la sociologie quantitative mainstream, i.e le « paradigme des variables » et ses hypothèses implicites souvent difficilement tenables (Abbott, 2001). Une bonne description solidement fondée théoriquement vaut bien des « modèles explicatifs » (Savage, 2009).

Trajectoires de soins : un exemple de données longitudinales

Dans ce chapitre, nous allons aborder plusieurs méthodes d’analyse à partir d’un jeu de données longitudinales. Tout d’abord, importons les données dans R avec la commande suivante :

load(url("http://larmarange.github.io/analyse-R/data/care_trajectories.RData"))
class(care_trajectories)
[1] "data.table" "data.frame"

Nous obtenons un objet appelé care_trajectories. La fonction class nous montre qu’il s’agit d’un tableau de données au format data.table (voir le chapitre dédié). Chargeons donc cette extension ainsi que le tidyverse.

library(tidyverse, quietly = TRUE)
library(data.table, quietly = TRUE)

Première description des données

Jetons un premier regard aux données.

head(care_trajectories)
id month care_status sex age education wealth distance_clinic
3 0 D 1 1 2 2 1
3 1 D 1 1 2 2 1
3 2 D 1 1 2 2 1
3 3 D 1 1 2 2 1
3 4 D 1 1 2 2 1
3 5 D 1 1 2 2 1

Il apparaît que les données sont dans un format long et tidy (voir le chapitre sur tidyr pour une présentation du concept de tidy data), avec une ligne par individu et par pas de temps. Il apparait également que les données sont stockées sous formes de vecteurs labellisés (voir le chapitre dédié aux vecteurs labellisés). Nous aurons donc besoin de l’extension labelled.

library(labelled)

Pour une description des variables, on pourra avoir recours à describe de questionr.

library(questionr)
describe(care_trajectories, freq.n.max = 10)
[49365 obs. x 8 variables] data.table data.frame

$id: patient identifier
integer: 3 3 3 3 3 3 9 9 13 13 ...
min: 3 - max: 9998 - NAs: 0 (0%) - 2929 unique values

$month: month(s) since diagnosis
numeric: 0 1 2 3 4 5 0 1 0 1 ...
min: 0 - max: 50 - NAs: 0 (0%) - 51 unique values

$care_status: care status
labelled character: "D" "D" "D" "D" "D" "D" "D" "D" "D" "D" ...
NAs: 0 (0%) - 4 unique values
4 value labels: [D] diagnosed, but not in care [C] in care, but not on treatment [T] on treatment, but infection not suppressed [S] on treatment and suppressed infection

                                                   n     %
[D] diagnosed, but not in care                 25374  51.4
[C] in care, but not on treatment               5886  11.9
[T] on treatment, but infection not suppressed  4596   9.3
[S] on treatment and suppressed infection      13509  27.4
Total                                          49365 100.0

$sex: sex
labelled double: 1 1 1 1 1 1 1 1 0 0 ...
min: 0 - max: 1 - NAs: 0 (0%) - 2 unique values
2 value labels: [0] male [1] female

               n   %
[0] male   17781  36
[1] female 31584  64
Total      49365 100

$age: age group
labelled double: 1 1 1 1 1 1 2 2 2 2 ...
min: 1 - max: 3 - NAs: 0 (0%) - 3 unique values
3 value labels: [1] 16-29 [2] 30-59 [3] 60+

              n     %
[1] 16-29 16911  34.3
[2] 30-59 29365  59.5
[3] 60+    3089   6.3
Total     49365 100.0

$education: education level
labelled double: 2 2 2 2 2 2 3 3 2 2 ...
min: 1 - max: 3 - NAs: 0 (0%) - 3 unique values
3 value labels: [1] primary [2] secondary [3] higher

                  n     %
[1] primary   10417  21.1
[2] secondary 19024  38.5
[3] higher    19924  40.4
Total         49365 100.0

$wealth: wealth group (assets score)
labelled double: 2 2 2 2 2 2 2 2 1 1 ...
min: 1 - max: 3 - NAs: 0 (0%) - 3 unique values
3 value labels: [1] low [2] middle [3] high

               n     %
[1] low    15432  31.3
[2] middle 20769  42.1
[3] high   13164  26.7
Total      49365 100.0

$distance_clinic: distance to nearest clinic
labelled double: 1 1 1 1 1 1 2 2 2 2 ...
min: 1 - max: 2 - NAs: 0 (0%) - 2 unique values
2 value labels: [1] less than 10 km [2] 10 km or more

                        n     %
[1] less than 10 km 26804  54.3
[2] 10 km or more   22561  45.7
Total               49365 100.0

Dans cette étude, on a suivi des patients à partir du moment où ils ont été diagnostiqués pour une pathologie grave et chronique et on a suivi leurs parcours de soins chaque mois à partir du diagnostic. La variable status contient le statut dans les soins de chaque individu pour chaque mois de suivi :

  • D : s’il n’est pas actuellement suivi dans une clinique, soit que la personne n’est pas encore entrée en clinique après le diagnostic, soit qu’elle a quitté la clinique et qu’elle est donc sortie des soins ;
  • C : indique que le patient est entré en soins (il est suivi dans une clinique) mais il n’a pas encore commencé le traitement, ou bien il a arrêté le traitement mais est toujours suivi en clinique ;
  • T : la personne est sous traitement mais l’infections n’est pas supprimée ou contrôlée, soit que le traitement n’a pas encore eu le temps de faire effet, soit qu’il n’est plus efficace ;
  • S : la personne est suivie en clinique, sous traitement et son infection est supprimée / contrôlée, indiquant que le traitement est efficace et produit son effet. Cette étape ultime du parcours de soins est celle dans laquelle on souhaite maintenir les individus le plus longtemps possible.

Il est important de noter que nous avons ici des statuts hiérarchiquement ordonnés (D < C < T < S), ce qui aura son importance pour les choix méthodologiques que nous aurons à faire.

Nous disposons également d’autres variables (âge, sexe, niveau d’éducation…) qui sont ici dépendantes du temps, c’est-à-dire que le cas échéant, elles peuvent varier d’un mois à l’autre en cas de changement.

Avant de démarrer les analyses, françisons certaines de ces variables.

var_label(care_trajectories$sex) <- "Sexe"
val_labels(care_trajectories$sex) <- c(homme = 0, femme = 1)
var_label(care_trajectories$age) <- "Âge"
var_label(care_trajectories$education) <- "Education"
val_labels(care_trajectories$education) <- c(
  primaire = 1,
  secondaire = 2,
  supérieur = 3
)

Le fichier contient 49 365 lignes, ce qui ne veut pas dire qu’il y a ce nombre d’invidus suivis au cours du temps, puisque plusieurs lignes correspondent à un même individu. On peut obtenir le nombre d’individus différents assez facilement avec la commande :

length(unique(care_trajectories$id))
[1] 2929

Précision : dans ce fichier, tous les individus ne sont pas suivis pendant la même durée, car ils n’ont pas tous été diagnostiqués au même moment. Cependant, il n’y a pas de trous dans le suivi (ce qui serait le cas si certains individus sortaient de l’observation pendant quelques mois puis re-rentraient dans la cohorte de suivi).

Avant d’aller plus avant, il nous faut avoir une idée du nombre d’individus observé au cours du temps, ce que l’on peut obtenir avec :

ggplot(care_trajectories) +
  aes(x = month) +
  geom_bar()

Améliorons ce graphique en y ajoutant la distribution selon le statut dans les soins chaque mois, en améliorant l’axe du temps (tous les 6 mois est plus facile à lire) et en y ajoutant un titre et des étiquettes appropriées. Afin de disposer d’une palette de couleurs à fort contraste, nous allons utiliser l’extension viridis. Enfin, nous allons utiliser une petite astuce pour indiquer les effectifs sur l’axe horizontal. Au passage, nous allons également franciser les étiquettes de la variable care_status avec val_labels (notez aussi le recours à to_factor dans aes qui nous permet de transformer à la volée la variable en facteur, format attendu par ggplot2 pour les variables catégorielles). On se référera au chapitre dédié à ggplot2 pour plus de détails sur les différentes fonctions de cette extension graphique.

library(viridis)
n <- care_trajectories[month %in% (0:8*6), .(n = .N), by = month]$n
etiquettes <- paste0("M", 0:8*6, "\n(n=", n, ")")
val_labels(care_trajectories$care_status) <- c(
  "diagnostiqué, mais pas suivi" = "D",
  "suivi, mais pas sous traitement" = "C",
  "sous traitement, mais infection non contrôlée" = "T",
  "sous traitement et infection contrôlée" = "S"
)
ggplot(care_trajectories) +
  aes(x = month, fill = to_factor(care_status)) +
  geom_bar(color = "gray50", width = 1) +
  scale_x_continuous(breaks = 0:8*6, labels = etiquettes) +
  ggtitle("Distribution du statut dans les soins chaque mois") +
  xlab("") + ylab("") +
  theme_light() +
  theme(legend.position = "bottom") +
  labs(fill = "Statut dans les soins") + 
  scale_fill_viridis(discrete = TRUE, direction = -1) +
  guides(fill = guide_legend(nrow = 2))

On s’aperçoit qu’une majorité des personnes suivies ne l’ont été que peu de temps, avec une décroissance rapide des effectifs.

Évolution de la cascade de soins au cours du temps

On nomme communément cascade de soins la proportion d’individus dans chaque statut à un moment du temps donné. On peut facilement obtenir celle-ci à partir du code du graphique précédent en ajoutant l’option position = fill à geom_bar.

ggplot(care_trajectories) +
  aes(x = month, fill = to_factor(care_status)) +
  geom_bar(color = "gray50", width = 1, position = "fill") +
  scale_x_continuous(breaks = 0:8*6, labels = etiquettes) +
  scale_y_continuous(labels = scales::percent) +
  ggtitle("Cascade des soins observée, selon le temps depuis le diagnostic") +
  xlab("") + ylab("") +
  theme_light() +
  theme(legend.position = "bottom") +
  labs(fill = "Statut dans les soins") + 
  scale_fill_viridis(discrete = TRUE, direction = -1) +
  guides(fill = guide_legend(nrow = 2))

Les effectifs sont très faibles au-delà de 36 mois et il serait préférable de couper la cascade au-delà de M36, ce que l’on peut faire aisément ne gardant que les lignes correspondantes de care_trajectories.

casc_obs <- ggplot(care_trajectories[month <= 36]) +
  aes(x = month, fill = to_factor(care_status)) +
  geom_bar(color = "gray50", width = 1, position = "fill") +
  scale_x_continuous(breaks = 0:8*6, labels = etiquettes) +
  scale_y_continuous(labels = scales::percent) +
  ggtitle("Cascade des soins observée, selon le temps depuis le diagnostic") +
  xlab("") + ylab("") +
  theme_light() +
  theme(legend.position = "bottom") +
  labs(fill = "Statut dans les soins") + 
  scale_fill_viridis(discrete = TRUE, direction = -1) +
  guides(fill = guide_legend(nrow = 2))
casc_obs

Analyse de survie classique

L’analyse de survie constitue l’approche statistique la plus fréquente pour appréhender des données biographiques. Dans sa version classique, l’analyse de survie modélise le temps mis pour vivre un événement particulier à partir d’un événement origine.

Dans notre exemple, l’événement d’origine commun à tous les individus est le diagnostic VIH. Les personnes suivies peuvent vivre trois événements principaux :

  • entrée en soins (passage de D à C) ;
  • initiation du traitement (passage de C à T) ;
  • contrôle de l’infection (passage de T à S).

En toute rigueur, il faudrait également considérer les transitions inverses (sortie de soins, arrêt du traitement, échec virologique). De même, il est possible que certains aient vécus plusieurs transitions successives (entrée en soin, initiation du traitement, sortie de soins et arrêt du traitement, nouvelle entrée en soins…).

Pour le moment, contentons-nous de regarder la première entrée en soins, la première initiation du traitement et la première atteinte du contrôle de l’infection et de calculer la date de ces trois événements, dans un fichier ind contenant une ligne par individu.

ind <- care_trajectories[month == 0]
ind$diagnostic <- 0
ind <- merge(
  ind,
  care_trajectories[
    care_status %in% c("C", "T", "S"), 
    .(entree_soins = min(month)),
    by = id
  ],
  by = "id", 
  all.x = TRUE
)
ind <- merge(
  ind,
  care_trajectories[
    care_status %in% c("T", "S"), 
    .(initiation_tt = min(month)),
    by = id
  ],
  by = "id", 
  all.x = TRUE
)
ind <- merge(
  ind,
  care_trajectories[
    care_status == "S", 
    .(controle = min(month)),
    by = id
  ],
  by = "id", 
  all.x = TRUE
)

Il nous faut également la durée de suivi par individu.

ind <- merge(
  ind,
  care_trajectories[, .(suivi = max(month)), by = id],
  by = "id", 
  all.x = TRUE
)

Pour faciliter la suite des analyses, nous allons nous créer une petite fonction qui, en fonction de la date d’origine et la date d’événement retenues, calculera la courbe de Kaplan-Meier correspondante (voir le chapitre sur l’analyse de suivie pour le calcul de la courbe de survie et celui dédié à l’écriture de fonctions).

km <- function(date_origine, date_evenement, nom) {
  library(survival)
  
  # ne garder que les observations avec date d'origine
  tmp <- ind[!is.na(ind[[date_origine]]), ]
  
  # pre-remplir la variable time avec duree de suivi
  # depuis date d'origine
  tmp$time <- tmp$suivi - tmp[[date_origine]]
  # et considérer que l'événement n'a pas été vécu
  tmp$event <- FALSE
  
  # si date_evement documentée, événement vécu
  tmp[!is.na(tmp[[date_evenement]]), ]$event <- TRUE
  tmp[tmp$event == TRUE, ]$time <- 
    tmp[tmp$event == TRUE, ][[date_evenement]] -
    tmp[tmp$event == TRUE, ][[date_origine]]
  
  kaplan <- survfit(Surv(time, event) ~ 1, data = tmp)
  res <- broom::tidy(kaplan, conf.int = TRUE)
  res$nom <- nom
  res
}

Une première approche consiste à regarder la survenue de chacun des trois événements mentions plus haut en fonction du temps depuis le diagnostic.

depuis_diag <- dplyr::bind_rows(
  km("diagnostic", "entree_soins", "entrée en soins"),
  km("diagnostic", "initiation_tt", "initiation du traitement"),
  km("diagnostic", "controle", "contrôle de l'infection")
)

g_diag <- ggplot(data = depuis_diag) +
  aes(x = time, y = 1 - estimate, 
      color = as_factor(nom), fill = as_factor(nom),
      ymin = 1 - conf.high, ymax = 1 - conf.low) +
  geom_ribbon(alpha = .25, mapping = aes(color = NULL)) +
  geom_line(size = 1) +
  theme_classic() +
  theme(
    legend.position = "bottom",
    panel.grid.major.y = element_line(colour = "grey")
  ) +
  scale_x_continuous(breaks = 0:6*6, limits = c(0, 36)) +
  scale_y_continuous(labels = scales::percent, limits = c(0, 1)) +
  xlab("mois depuis le diagnostic") + 
  ylab("") + labs(color = "", fill = "")
g_diag

Ce graphique ressemble à la cascade des soins observée que nous avions calculée plus haut, à quelques différences près :

  • avec la méthode de Kaplan-Meier, la censure à droite, i.e. le fait que tous les individus n’ont pas la même durée de suivi, est correctement prise en compte et la courbe est corrigée en conséquence ;
  • par contre, les transitions inverses ne sont pas considérées : lorsqu’un individu a atteint une étape, on ne regarde pas s’il en ressort.

Une autre manière d’appréhender nos trajectoires est de considérer le temps requis pour atteindre une étape une fois la précédente étape atteinte. Ce qu’on obtient facilement en adaptant légèrement notre code précédent.

depuis_prec <- dplyr::bind_rows(
  km("diagnostic", "entree_soins", "entrée en soins"),
  km("entree_soins", "initiation_tt", "initiation du traitement"),
  km("initiation_tt", "controle", "contrôle de l'infection")
)

g_prec <- ggplot(data = depuis_prec) +
  aes(x = time, y = 1 - estimate, 
      color = as_factor(nom), fill = as_factor(nom),
      ymin = 1 - conf.high, ymax = 1 - conf.low) +
  geom_ribbon(alpha = .25, mapping = aes(color = NULL)) +
  geom_line(size = 1) +
  theme_classic() +
  theme(
    legend.position = "bottom",
    panel.grid.major.y = element_line(colour = "grey")
  ) +
  scale_x_continuous(breaks = 0:6*6, limits = c(0, 36)) +
  scale_y_continuous(labels = scales::percent, limits = c(0, 1)) +
  xlab("mois depuis l'étape précédente") + 
  ylab("") + labs(color = "", fill = "")

g_prec

Attention : cette représentation graphique peut éventuellement prêter à confusion dans sa lecture car l’échelle de temps n’est pas tout à fait la même pour chaque courbe, dans la mesure où la date d’origine diffère pour chacune. Dès lors, il peut être plus pertinent de présenter chaque courbe l’une à côté de l’autre.

g_prec + facet_grid(~ as_factor(nom))

Ici, on voit plus clairement que l’étape où il y a le plus de perdition est celle de l’entrée en soins, moins des trois quarts des personnes diagnostiquées étant venu en clinique au mois une fois dans les trois ans suivant le diagnostic. Par contre, l’initiation du traitement une fois entré en clinique et le contrôle de l’infection une fois le traitement initié sont beaucoup plus rapide.

Pour aller plus loin avec les outils de l’analyse de survie classique, il serait possible de faire des analyses bivariées (Kaplan-Meier) ou multivariées (Cox) pour chacune de ces étapes. Cependant, il serait plus intéressant de trouver une approache statistique permettant de considérer dans un même modèle l’ensemble des transitions possibles.

Une première analyse de séquences sur l’ensemble du fichier

L’analyse de séquences permet d’appréhender l’ensemble de la trajectoire de soins à travers la succession des états dans lesquels se trouvent les patients observés.

Nous allons donc réaliser une analyse de séquences (voir le chapitre dédié) sur l’ensemble de notre fichier. Pour cela, il va falloir préalable que nous transformions nos donnée actuellement dans un format long en un tableau large, c’est-à-dire avec une ligne par individu et une variable différentes par pas de temps. On peut réaliser cela facilement avec pivot_wider de tidyr (voir le chapitre dédié à tidyr). Il faut noter que le résultat ne sera pas un tableau data.table, d’où le recours à setDT pour convertir le résultat.

library(tidyr)
large <- care_trajectories %>%
  dplyr::select(id, m = month, care_status) %>%
  pivot_wider(names_from = m, values_from = care_status, names_prefix = "m") 
setDT(large)
head(large)
id m0 m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12 m13 m14 m15 m16 m17 m18 m19 m20 m21 m22 m23 m24 m25 m26 m27 m28 m29 m30 m31 m32 m33 m34 m35 m36 m37 m38 m39 m40 m41 m42 m43 m44 m45 m46 m47 m48 m49 m50
3 D D D D D D NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
9 D D NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
13 D D D D D D D D NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
15 D D D D T T T C D D D D D D D C C C C C C C C C T T T T T T T T T NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
18 D D S S S S S S S S S S S S S S S S S NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
21 D D D D D D NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA

On utilise seqdef de TraMineR pour créer nos séquences, avec les arguments alphabet pour forcer l’ordre de l’alphabet, states pour spécifier des étiquettes courtes à chaque état et cpal pour indiquer le code couleur de chaque état (et être raccord avec nos graphiques précédents).

library(TraMineR, quietly = TRUE)

TraMineR stable version 2.2-1 (Built: 2020-11-02)
Website: http://traminer.unige.ch
Please type 'citation("TraMineR")' for citation information.
seq_all <- seqdef(
  large[, m0:m50],
  id = large$id,
  alphabet = c("D", "C", "T", "S"),
  states = c("diagnostiqué", "en soins", "sous traitement", "inf. contrôlée"),
  cpal = viridis(4, direction = -1)
)
 [>] found missing values ('NA') in sequence data
 [>] preparing 2929 sequences
 [>] coding void elements with '%' and missing values with '*'
 [>] state coding:
       [alphabet]  [label]         [long label] 
     1  D           diagnostiqué    diagnostiqué
     2  C           en soins        en soins
     3  T           sous traitement sous traitement
     4  S           inf. contrôlée  inf. contrôlée
 [>] 2929 sequences in the data set
 [>] min/max sequence length: 1/51

On peut retrouver la cascade de soins avec seqdplot.

seqdplot(seq_all, legend.prop = .25)

Nous allons maintenant calculer une matrice des distances entre individus par optimal matching. Dans le cas présent, nos différents status sont hiérarchiquement ordonnés. Il n’est donc pas raisonnable de penser que les coûts sont constants entre les différents statuts, puisqu’en un sens, passer directement de D à T peut être considéré comme être passé d’abord de D à C puis de C à D. Nous allons donc faire une matrice de coûts hiérarchisée. seqcost nous permets de produire une matrice de coûts constants, que nous allons ensuite modifier manuellement. Pour le coût indel, le plus simple est de considérer la moitié du coût de substitution maximum.

couts <- seqcost(seq_all, method = "CONSTANT")
 [>] creating 4x4 substitution-cost matrix using 2 as constant value
couts
$indel
[1] 1

$sm
                  diagnostiqué-> en soins->
diagnostiqué->                 0          2
en soins->                     2          0
sous traitement->              2          2
inf. contrôlée->               2          2
                  sous traitement-> inf. contrôlée->
diagnostiqué->                    2                2
en soins->                        2                2
sous traitement->                 0                2
inf. contrôlée->                  2                0
couts$sm[1, ] <- c(0, 1, 2, 3)
couts$sm[2, ] <- c(1, 0, 1, 2)
couts$sm[3, ] <- c(2, 1, 0, 1)
couts$sm[4, ] <- c(3, 2, 1, 0)
couts$indel <- max(couts$sm) / 2
couts
$indel
[1] 1.5

$sm
                  diagnostiqué-> en soins->
diagnostiqué->                 0          1
en soins->                     1          0
sous traitement->              2          1
inf. contrôlée->               3          2
                  sous traitement-> inf. contrôlée->
diagnostiqué->                    2                3
en soins->                        1                2
sous traitement->                 0                1
inf. contrôlée->                  1                0
dist_all <- seqdist(seq_all, method = "OM", sm = couts$sm, indel = couts$indel)
 [>] 2929 sequences with 4 distinct states
 [>] checking 'sm' (size and triangle inequality)
 [>] 1370 distinct  sequences 
 [>] min/max sequence lengths: 1/51
 [>] computing distances using the OM metric
 [>] elapsed time: 2.55 secs

Calculons le dendrogramme et représentons le avec le tapis de séquence grace à seq_heatmap de l’extension JLutils. Pour rappel, cette extension est seulement disponible sur GitHub. On l’installera donc (ou on la mettra à jour) avec la commande devtools::install_github("larmarange/JLutils").

arbre_all <- hclust(as.dist(dist_all), method = "ward.D2")
library(JLutils, quietly = TRUE)
seq_heatmap(seq_all, arbre_all)

Il apparaît que les différentes séquences sont principalement regroupées en fonction de leur longueur. En effet, pour passer d’une séquence courte à une séquence longue il faut ajouter des statuts pour compléter la séquence ce qui induit de facto une distance élevée (en raison du coût indel). Dès lors, lorsque l’on travaille avec des séquences aux longueurs très disparates, une classification ascendante hiérarchique va produire une typologie de séquences courtes et de séquences longues, ce qui n’est pas forcément ce que l’on recherche.

Dans notre exemple, nous pouvons considérer que les séquences courtes ne sont pas pertinentes à retenir dans l’analyse car l’observation n’est pas assez longue pour voir le parcours de soins des patients. Une solution consiste à ne retenir que les individus observées au moins n mois et analyser leur trajectoire sur seulement n mois, ce qui permet de n’avoir que des séquences de même longueur. Dès lors, la distance entre deux séquences ne dépendra plus que des différences de parcours. On serait tenté de prendre un n élévé pour avoir ainsi des parcours de soins longs. Mais dans ce cas là, l’analyse ne se fera que sur un tout petit nombre d’individus et on manquera de puissance. Si, à l’inverse, on prends un n petit, nous aurons des effectifs élevés mais les séquences seront peut-être trop courtes pour mettre en évidence la variété des trajectoires. Il faut dès lors trouver un compromis entre ces deux contraintes.

Si l’on regarde notre premier graphique montrant le nombre d’observations au cours du temps, il apparaît une sorte de point d’inflexion au niveau de M18 avec un brusque décrochage. D’un autre côté, 18 mois offre un minimum de durée d’observations pour espérer voir émerger des trajectoires plus complexes.

Une seconde analyse de séquences limitées aux 18 premiers mois

Reprenons notre analyse en se limitant aux individus observés au moins 18 mois (soit 19 status entre M0 et M18) et en se limitant aux 18 premiers mois pour modéliser les séquences. La fonction seqlength permets de récupérer la longueur de chaque séquence.

large$seq_length <- seqlength(seq_all)
large_m18 <- large[seq_length >= 19, id:m18]
seq_m18 <- seqdef(
  large_m18[, m0:m18],
  id = large_m18$id,
  alphabet = c("D", "C", "T", "S"),
  states = c("diagnostiqué", "en soins", "sous traitement", "inf. contrôlée"),
  cpal = viridis(4, direction = -1)
)
 [>] state coding:
       [alphabet]  [label]         [long label] 
     1  D           diagnostiqué    diagnostiqué
     2  C           en soins        en soins
     3  T           sous traitement sous traitement
     4  S           inf. contrôlée  inf. contrôlée
 [>] 1317 sequences in the data set
 [>] min/max sequence length: 19/19
dist_m18 <- seqdist(seq_m18, method = "OM", sm = couts$sm, indel = couts$indel)
 [>] 1317 sequences with 4 distinct states
 [>] checking 'sm' (size and triangle inequality)
 [>] 578 distinct  sequences 
 [>] min/max sequence lengths: 19/19
 [>] computing distances using the OM metric
 [>] elapsed time: 0.33 secs
arbre_m18 <- hclust(as.dist(dist_m18), method = "ward.D2")
seq_heatmap(seq_m18, arbre_m18)

Reste maintenant à décider du nombre de classes à retenir. Encore une fois, c’est un équilibre à trouver entre le niveau de détails voulus et le niveau de simplification requis pour permettre l’analyse.

Pour faciliter ce choix, on peut avoir recours à la fonction as.seqtree de l’extension WeightedCluster, couplée à la fonction seqtreedisplay. ATTENTION : pour que le graphique puisse être produit, il faut que le logiciel libre GraphViz (https://graphviz.gitlab.io/) soit installé sur votre PC. On peut également installer GraphViz avec le code ci-dessous :

if (!requireNamespace("BiocManager", quietly = TRUE))
    install.packages("BiocManager")
BiocManager::install("Rgraphviz")

La combinaison des deux fonctions va permettre de représenter l’évolution des catégories au fur-et-à-mesure que l’on coupe le dendrogramme plus bas. On peut choisir le type de graphique utilisé avec l’argument type (voir l’aide de seqplot) et le nombre maximum de clusters avec nclust.

library(WeightedCluster, quietly = TRUE)
seqtree_m18 <- as.seqtree(arbre_m18, seqdata = seq_m18, diss = dist_m18, ncluster = 7)
seqtreedisplay(seqtree_m18, type="I", border=NA, show.depth=TRUE)

Représentation graphique produite par seqtreedisplay

Afin d’éviter de multiplier les sous-groupes, nous n’allons conserver que 4 catégories.

large_m18$typo_cah <- cutree(arbre_m18, 4)

Il est aussi possible de se baser sur divers indicateurs statistiques sur la qualité de chaque partition. Pour cela, on pourra par exemple avoir recours à la fonction as.clustrange de l’extension WeightedCluster. Essayez par exemple les commandes ci-après :

nc <- as.clustrange(arbre_m18, dist_m18)
summary(nc, max.rank = 3)
plot(nc, norm = "zscore")

Pour plus d’informations, voir le manuel de la librairie WeightedCluster, chapitre 7.

On peut représenter le découpage du dendrogramme avec A2Rplot fournie par JLutils

A2Rplot(arbre_m18, k = 4, show.labels = FALSE)

Comme expliqué par Matthias Studer dans le manuel de la librairie WeightedCluster, plusieurs critiques peuvent être adressées aux procédures hiérarchiques, en particulier le fait que la fusion de deux groupes se fait en maximisant un critère local.

L’algorithme PAM pour Partitioning Around Medoids suit une autre logique que les algorithmes hiérarchiques et vise à obtenir la meilleure partition d’un ensemble de données en un nombre prédéfini de groupes. Il a l’avantage de maximiser un critère global et non uniquement un critère local. Par contre, le nombre de classes doit être fixé à l’avance.

Ayant décidé de retenir 4 classes au regard de notre classification ascendante hiérarchique, nous pouvons voir si l’algorithme PAM permets d’améliorer nos 4 classes. Nous allons utiliser la fonction wcKMedoids de l’extension WeightedCluster en lui indiquant comme partition initiale celle obtenue avec la classigication hiérarchique.

pam_m18 <- wcKMedoids(dist_m18, k = 4, initialclust = arbre_m18)
large_m18$typo_pam <- pam_m18$clustering

Un tableau croisé nous permets de voir que les deux typologies restent proches.

table(large_m18$typo_cah, large_m18$typo_pam)
/ 6 23 85 410
1 522 4 0 39
2 0 3 330 3
3 1 203 59 13
4 23 0 5 112

Regardons les tapis de séquence des deux typologies.

large_m18$ordre_cmd <- cmdscale(as.dist(dist_m18), k = 1)
seqIplot(seq_m18, group = large_m18$typo_cah, sortv = large_m18$ordre_cmd)

seqIplot(seq_m18, group = large_m18$typo_pam, sortv = large_m18$ordre_cmd)

Comme on le voit les deux typologies obtenues sont très proches. Suivant le cas, à vous de choisir celle qui semble la plus pertinente d’un point de vue sociologique. Il existe également divers indicateurs statisques pour mesurer la qualité d’une partition (voir le manuel de la librairie WeightedCluster de Matthias Studer). Ils peuvent être calculés avec la fonction wcClusterQuality. Comparons les deux typologies obtenues.

tab <- tibble(
  stat = names(wcClusterQuality(dist_m18, large_m18$typo_cah)$stats),
  cah = wcClusterQuality(dist_m18, large_m18$typo_cah)$stats,
  pam = wcClusterQuality(dist_m18, large_m18$typo_pam)$stats
)
gt::gt(tab) %>% gt::fmt_number(2:3, decimals = 2, sep_mark = " ")
stat cah pam
PBC 0.70 0.71
HG 0.93 0.95
HGSD 0.93 0.95
ASW 0.53 0.57
ASWw 0.53 0.57
CH 938.97 1 023.12
R2 0.68 0.70
CHsq 3 351.21 3 980.60
R2sq 0.88 0.90
HC 0.03 0.02

Selon ces indicateurs calculés, l’approche PAM obtiendrait une partition légèrement de meilleure qualité que celle obtenuepar CAH.

L’extension WeightedCluster fournie aussi une fonction wcSilhouetteObs permettant de mesurer la silhouette de chaque séquence. Plus cette métrique est élevée et proche de 1, plus la séquence est proche du centre de classe et caractéristique de la classe. On peut utiliser cette métrique pour classer les séquences sur le tapis de séquences.

large_m18$sil <- wcSilhouetteObs(dist_m18, large_m18$typo_pam)
seqIplot(seq_m18, group = large_m18$typo_pam, sortv = large_m18$sil)

Nous voyons émerger quatre groupes distincts :

  • les rapides, qui entrent en soins et initient le traitement dès les premiers mois suivant le diagnostic ;
  • les lents, qui entrent en soins et initient le traitement plus tardivement, après M6 ;
  • les inaboutis, qui entrent en soins mais n’initient pas le traitement ;
  • les hors soins, qui ne sont pas entrés en soins où n’y sont pas restés.

Le graphique obtenu avec seqIplot affiche visuellement chaque groupe avec la même hauteur, pouvant laisser accroire que chaque groupe a le même poids dans l’échantillon. Pour produire une représentation graphique des tapis de séquences plus correcte, où chaque la hauteur de chaque groupe correspondrait à son poids dans l’échantillon, nous allons passer par ggplot2. Un tapis de séquences peut-être vu comme un raster et dès lors représenté avec geom_raster. Pour travailler avec ggplot2, nos données doivent être au format tidy, c’est-à-dire avec une ligne par point d’observation, soit une ligne par personne et par jour. Nous allons donc repartir du fichier care_trajectories. Le mois d’observation indiquera la position en abscisse. Quant à la position en ordonnée, il faudra que nous la calculions, séparément pour chaque groupe, afin d’éviter des lignes vides dans le graphique.

# nommer les groupes
large_m18$groupe <- factor(
  large_m18$typo_pam,
  c(85, 23, 410, 6),
  c("Rapides", "Lents", "Inaboutis", "Hors soins")
)

# calculer le rang des individus dans chaque groupe
setorder(large_m18, "ordre_cmd")
large_m18[, rang_cmd := 1:.N, by = groupe]

# créer un fichier long
long_m18 <- care_trajectories[id %in% large_m18$id & month <= 18]
long_m18 <- merge(
  long_m18,
  large_m18[, .(id, groupe, rang_cmd)],
  by = "id",
  all.x = TRUE
)
long_m18$care_statusF <- to_factor(long_m18$care_status)

# calculer les effectifs par groupe
tmp <- large_m18[, .(n = .N), by = groupe]
tmp[, groupe_n := paste0(groupe, "\n(n=", n, ")")]
long_m18 <- merge(
  long_m18,
  tmp[, .(groupe, groupe_n)],
  by = "groupe",
  all.x = TRUE
)
# graphique des tapis de séquences
ggplot(long_m18) +
  aes(x = month, y = rang_cmd, fill = care_statusF) +
  geom_raster() +
  facet_grid(groupe_n ~ ., space = "free", scales = "free") +
  scale_x_continuous(breaks = 0:6*3, labels = paste0("M", 0:6*3)) +
  scale_y_continuous(breaks = 0:5*100, minor_breaks = NULL) +
  xlab("") + ylab("") +
  theme_light() +
  theme(legend.position = "bottom") +
  labs(fill = "Statut dans les soins") + 
  scale_fill_viridis(discrete = TRUE, direction = -1) +
  guides(fill = guide_legend(nrow = 2))

Facteurs associés à l’appartenance à chaque groupe

Une fois les différents groupes de trajectoires identifiés, il est courant de vouloir regarder si certains facteurs influencent l’appartenance à un groupe plutôt qu’un autre. Dans nos données d’exemple, nous nous intéresserons aux variables suivantes : sexe, groupe d’âges et niveau d’éducation.

Ces différentes variables sont renseignées pour chaque mois dans le tableau de données care_trajectories, en tenant compte des éventuels changements au cours du temps. Ici, notre analyse est menée au niveau individuel. Nous allons donc récupérer la valeur de ces différentes variables au moment du diagnostic, à savoir à M0.

large_m18 <- merge(
  large_m18,
  care_trajectories[
    month == 0, 
    .(id, sex, age, education)
  ],
  by = "id",
  all.x = TRUE
)

La fonction tbl_summary de l’extension gtsummary permets de produire aisément une série de tableaux croisés. À noter le recours à add_p() pour ajouter les p-valeurs au test du Chi².1 La fonction add_overall permets d’ajouter une colonne avec l’ensemble de l’échantillon. Notez que nous avons utiliser unlabelled de l’extension labelled pour convertir en amont les vecteurs labellisés en facteurs.

library(gtsummary)
unlabelled(large_m18) %>% 
  tbl_summary(by = "groupe", include = c("groupe", "sex", "age", "education")) %>%
  add_p() %>%
  add_overall(last = TRUE)
Caractéristique Rapides, N = 3941 Lents, N = 2101 Inaboutis, N = 1671 Hors soins, N = 5461 p-value2 Total, N = 1 3171
Sexe <0,001
homme 104 (26%) 61 (29%) 42 (25%) 243 (45%) 450 (34%)
femme 290 (74%) 149 (71%) 125 (75%) 303 (55%) 867 (66%)
Âge <0,001
16-29 96 (24%) 71 (34%) 62 (37%) 235 (43%) 464 (35%)
30-59 269 (68%) 128 (61%) 91 (54%) 281 (51%) 769 (58%)
60+ 29 (7,4%) 11 (5,2%) 14 (8,4%) 30 (5,5%) 84 (6,4%)
Education 0,002
primaire 63 (16%) 47 (22%) 30 (18%) 123 (23%) 263 (20%)
secondaire 126 (32%) 83 (40%) 61 (37%) 212 (39%) 482 (37%)
supérieur 205 (52%) 80 (38%) 76 (46%) 211 (39%) 572 (43%)

1 Statistique présentée: n (%)

2 Test statistique réalisé: test du khi-deux d'indépendance

Une manière de présenter ces mêmes données de manière plus visuelle consiste à réaliser un diagramme en barres cumulées (voir le chapitre sur les graphiques bivariés). Ici, nous utilisons une boucle for (voir le chapitre sur les structures conditionnelles) pour calculer les différents tableaux croisés et les fusionner avec bind_rows (voir la section concaténation de tables du chapitre dédié à dplyr). Nous en profitions également pour calculer le test du Chi² et l’afficher avec le nom de la variable sur le graphique.

Note : pour afficher les proportions sur le graphique, aurons recours recours à la statistique stat_prop de l’extension GGally.

res <- tibble()
explanatory <- c(
  "sex" = "Sexe", 
  "age" = "Âge",
  "education" = "Education"
)
for (v in names(explanatory)) {
  tmp <- tibble::as_tibble(table(large_m18$groupe, to_factor(large_m18[[v]])), .name_repair = "unique")
  names(tmp) <- c("groupe", "level", "n")
  test <- chisq.test(large_m18$groupe, to_factor(large_m18[[v]]))
  tmp$var <- paste0(
    explanatory[v],
    "\n",
    scales::pvalue(test$p.value, add_p = TRUE)
  )
  res <- bind_rows(res, tmp)
}


# stat_prop() a besoin d'un facteur
res$level <- factor(res$level)

library(GGally)
ggplot(res) +
  aes(x = level, fill = groupe, weight = n) +
  geom_bar(position = "fill") +
  geom_text(
    aes(by = level, label = scales::percent(..prop.., accuracy = 1)), 
    stat = "prop", position = position_fill(.5)
  ) +
  facet_grid(var ~ ., scales = "free", space = "free") +
  scale_y_continuous(labels = scales::percent, breaks = 0:5/5) +
  coord_flip() +
  theme(legend.position = "bottom") +
  xlab("") + ylab("") + labs(fill = "")

Un graphique similaire peut s’obtenir très facilement en ayant recours à la fonction ggbivariate de l’extension GGally2.

library(GGally)
ggbivariate(
  unlabelled(large_m18), 
  outcome = "groupe", 
  explanatory = c("sex", "age", "education"),
  columnLabelsY = c("Sex", "Âge", "Éducation")
) + labs(fill = "")

Pour mieux visualiser les relations entre les variables, on peut avoir recours à la fonction ggtable de l’extension GGally qui permets de représenter les résidus du Chi².

library(GGally)
ggtable(
  unlabelled(large_m18), 
  columnsX = "groupe", 
  columnsY = c("sex", "age", "education"),
  cells = "col.prop",
  fill = "std.resid",
  columnLabelsX = "Type de trajectoire", 
  columnLabelsY = c("Sex", "Âge", "Éducation"),
  legend = 1
) + 
  labs(fill = "Résidus standardizés du Chi²") +
  theme(legend.position = "bottom")

On considère qu’une cellule est surreprésentée si son résidu standardisé du Chi² est supérieur à 2 ou 3, et qu’elle est sous-représentée si le résidu est inférieur à -2 ou -3.

On peut ainsi noter que les hommes, les jeunes et ceux vivant à plus de 10 kilomètres d’une clinique sont plus souvent dans le groupe Hors soins. Inversement, les femmes et les plus éduqués sont plus souvent dans le groupe des Rapides. Résultat inattendu, les ménages les plus riches sont moins souvent dans les groupes ayant initiés un traitement (Rapides et Lents), ce résultat pouvant s’expliquer en partie par le fait que les plus aisés peuvent plus facilement accéder à des soins dans le secteur privé, et donc faussement apparaître Hors soins, car seuls les soins reçus dans le secteur public ont été mesurés dans cette étude.

Pour affiner les résultats, on aura recours à un modèle multivarié en exécutant une régression logistique multinomiale avec multinom de l’extension nnet (pour plus de détails, voir le chapitre dédié).

library(nnet)
large_m18$groupe2 <- relevel(large_m18$groupe, "Hors soins")
regm <- multinom(
  groupe2 ~ sex + age + education, 
  data = to_factor(large_m18)
)
tmp <- JLutils::tidy_detailed(regm, exponentiate = T, conf.int = TRUE)
tmp <- tmp[tmp$term != "(Intercept)", ]
ggplot(tmp) + 
  aes(x = label, y = estimate, ymin = conf.low, ymax = conf.high, color = y.level) +
  geom_hline(yintercept = 1, color = "gray25", linetype = "dotted") + 
  geom_errorbar(position = position_dodge(0.5), width = 0) + 
  geom_point(position = position_dodge(width = 0.5)) + 
  scale_y_log10() + 
  coord_flip() +
  xlab("Facteurs") + ylab("Odds Ratios") +
  labs(color = "vs. Hors Soins") +
  theme_light() + 
  theme(panel.grid.major.y = element_blank())

Nous pouvons représenter les effets des variables du modèle avec la fonction ggeffect de ggeffects.

library(ggeffects)
cowplot::plot_grid(plotlist = plot(ggeffect(regm)), ncol = 3)

Modèle mixte à classes latentes

Un autre type d’approche envisageable pour identifier des classes de trajectoires est celle des modèles mixtes à classes latentes. Ce type de modèles peut prendre en compte une grande variété d’indicateurs, continus, binaires ou ordinaux. On peut y intégrer des co-variables et il n’est pas nécessaire de disposer du même nombre d’observations par individu.

Nous n’aborderons que brièvement ici ce type de modèles complexes. Sous R, ils peuvent être réalisés via l’extension lcmm et sa fonction homonyme lcmm.

Commençons par préparer les données.

care_trajectories$num_status <- as.integer(to_factor(care_trajectories$care_status))
care_trajectories[, sexF := to_factor(sex)]
care_trajectories[, ageF := to_factor(age)]
care_trajectories[, educationF := to_factor(education)]

Ici, nous allons modéliser le statut dans les soins en fonction du temps. Il faut indiquer au modèle, via le paramètre ng le nombre de groupes ou classes latentes souhaité. Ici, nous avons retenu 4 en lien avec les résultats de notre analyse de séquences. L’argument link = "thresholds" permets d’indiquer que notre variable d’intérêt est ordinale. Les modèles lcmm peuvent également prendre en compte des variables continues.

Attention : le temps de calcul de ce type de modèle peut être long (plusieurs heures dans notre exemple), suivant le nombre de paramètres, le nombre d’observations et la puissance de votre machine.

library(lcmm)
mod4 <-lcmm(
  num_status ~ month, random = ~ month, subject = 'id', 
  mixture = ~ month, ng = 4, idiag = TRUE, data = care_trajectories, 
  link = "thresholds"
)

Voyons comment se présentent les résultats.

summary(mod4)
General latent class mixed model 
     fitted by maximum likelihood method 
 
lcmm(fixed = num_status ~ month, mixture = ~month, random = ~month, 
    subject = "id", ng = 4, idiag = TRUE, link = "thresholds", 
    data = care_trajectories)
 
Statistical Model: 
     Dataset: care_trajectories 
     Number of subjects: 2929 
     Number of observations: 49365 
     Number of latent classes: 4 
     Number of parameters: 15  
     Link function: thresholds  
 
Iteration process: 
     Convergence criteria satisfied 
     Number of iterations:  52 
     Convergence criteria: parameters= 5.2e-10 
                         : likelihood= 5.4e-07 
                         : second derivatives= 3.5e-07 
 
Goodness-of-fit statistics: 
     maximum log-likelihood: -26612.74  
     AIC: 53255.48  
     BIC: 53345.22  
 
     Discrete posterior log-likelihood: -26612.74  
     Discrete AIC: 53255.48  
 
     Mean discrete AIC per subject: 9.0911  
     Mean UACV per subject: 9.1045  
     Mean discrete LL per subject: -9.0859  
 
Maximum Likelihood Estimates: 
 
Fixed effects in the class-membership model:
(the class of reference is the last class) 

                     coef      Se    Wald p-value
intercept class1  0.00832 0.04503   0.185 0.85334
intercept class2 -0.42002 0.12990  -3.233 0.00122
intercept class3 -0.02992 0.09675  -0.309 0.75712

Fixed effects in the longitudinal model:

                                     coef      Se    Wald
intercept class1 (not estimated)        0                
intercept class2                 -1.49825 0.08163 -18.355
intercept class3                 -0.41418 0.05228  -7.923
intercept class4                 -2.50344 0.09211 -27.179
month class1                      0.21757 0.00332  65.447
month class2                      0.01032 0.00506   2.039
month class3                      0.17720 0.00338  52.373
month class4                      0.00449 0.00512   0.876
                                 p-value
intercept class1 (not estimated)        
intercept class2                 0.00000
intercept class3                 0.00000
intercept class4                 0.00000
month class1                     0.00000
month class2                     0.04142
month class3                     0.00000
month class4                     0.38090


Variance-covariance matrix of the random-effects:
          intercept   month
intercept   4.39542        
month       0.00000 0.12653

Residual standard error (not estimated) = 1

Parameters of the link function:

                  coef      Se    Wald p-value
thresh. parm1  0.94803 0.04753  19.945 0.00000
thresh. parm2  1.10727 0.00652 169.922 0.00000
thresh. parm3  1.08980 0.00727 149.816 0.00000

On dispose d’un AIC et d’un BIC. Ainsi, une stratégie possible pour déterminer le nombre de classes consiste à calculer un modèle différent pour chaque nombre de classes envisagé puis à retenir le modèle ayant le plus faible AIC ou BIC.

Pour chaque observation, le modèle a calculé la probabilité qu’elle appartienne à chacune des 4 classes identifiées. La fonction postprob fournit des statistiques sur cette classification.

postprob(mod4)
 
Posterior classification: 
  class1 class2 class3  class4
N 844.00 153.00 424.00 1508.00
%  28.82   5.22  14.48   51.49
 
Posterior classification table: 
     --> mean of posterior probabilities in each class 
        prob1  prob2  prob3  prob4
class1 0.5945 0.0735 0.2476 0.0844
class2 0.0924 0.7257 0.0881 0.0938
class3 0.1576 0.1103 0.6561 0.0760
class4 0.1522 0.2052 0.1865 0.4561
 
Posterior probabilities above a threshold (%): 
         class1 class2 class3 class4
prob>0.7  23.58  54.90  38.68   6.90
prob>0.8  15.88  48.37  30.19   4.97
prob>0.9  11.26  33.99  21.93   3.51
 

Les classes et les probabilités d’appartenance à chacune sont disponibles aisément.

head(mod4$pprob)
id class prob1 prob2 prob3 prob4
3 4 0.1686629 0.2218569 0.2016242 0.4078560
9 4 0.2123759 0.2051987 0.2329009 0.3495245
13 4 0.1590213 0.2260205 0.1879610 0.4269972
15 1 0.9992106 0.0000000 0.0000004 0.0007890
18 1 0.5616344 0.0472977 0.3478822 0.0431858
21 4 0.1686629 0.2218569 0.2016242 0.4078560

Récupérons la classe dans notre fichier de données.

care_trajectories <- merge(
  care_trajectories,
  mod4$pprob %>% dplyr::select(id, mod4_class = class),
  by = "id",
  all.x = TRUE
)

Améliorons les intitulés des classes et ajoutons le nombre d’individu par classes.

n_par_classe <- table(mod4$pprob$class)
n_par_classe
1 2 3 4
844 153 424 1508
care_trajectories$mod4_class2 <- factor(
  care_trajectories$mod4_class,
  levels = 1:4,
  labels = paste0(
    "Classe ",
    1:4,
    " (n=",
    n_par_classe,
    ")"
  )
)

Représentons la cascade observée dans chacune de ces classes.

care_trajectories$care_statusF <- to_factor(care_trajectories$care_status)
ggplot(care_trajectories[month <= 36]) +
  aes(x = month, fill = care_statusF) +
  geom_bar(color = "gray50", width = 1, position = "fill") +
  scale_x_continuous(breaks = 0:6*6, labels = paste0("M", 0:6*6)) +
  scale_y_continuous(labels = scales::percent) +
  xlab("") + ylab("") +
  theme_light() +
  theme(legend.position = "bottom") +
  labs(fill = "Statut dans les soins") + 
  scale_fill_viridis(discrete = TRUE, direction = -1) +
  guides(fill = guide_legend(nrow = 2)) +
  facet_grid(~ mod4_class2)

Une manière alternative de présenter les classes consiste à représenter chaque mois, non pas la distribution dans chaque état, mais un état moyen en considérant que le statut dans les soins peut être assimilé à un score allant de 1 à 4.

moyennes_mensuelles <- care_trajectories[
  month <= 36, 
  .(status_moyen = mean(num_status)), 
  by = .(month, mod4_class2)
]
ggplot(moyennes_mensuelles) + 
  aes(x = month, y = status_moyen, color = mod4_class2) +
  geom_line(size = 2) +
  scale_x_continuous(breaks = 0:6*6, labels = paste0("M", 0:6*6)) +
  scale_y_continuous(
    breaks = 1:4, limits = c(1, 4),
    labels = c("diagnostiqué", "suivi", "sous traitement", "contrôlé")
  ) +
  xlab("") + ylab("Statut moyen") + labs(color = "") +
  theme_classic() +
  theme(
    legend.position = "bottom", 
    panel.grid.major = element_line(colour = "grey80")
  )

Il faut cependant rester vigilant, dans la mesure où ce type de représentation synthétique peut masquer la diversité des trajectoires sous-jacentes, notamment en termes de durée ou d’enchaînement des événements. Même si cela est peut-être plus difficile à lire, il est toujours bon de regarder les tapis de séquences.

care_trajectories[, tmp_rang := as.integer(fct_infreq(factor(id))), by = mod4_class]
ggplot(care_trajectories[month <= 36]) +
  aes(x = month, y = tmp_rang, fill = care_statusF) +
  geom_raster() +
  facet_grid(mod4_class2 ~ ., space = "free", scales = "free") +
  scale_x_continuous(breaks = 0:6*6, labels = paste0("M", 0:6*6)) +
  scale_y_continuous(breaks = 0:5*200, minor_breaks = NULL) +
  xlab("") + ylab("") +
  theme_light() +
  theme(legend.position = "bottom") +
  labs(fill = "Statut dans les soins") + 
  scale_fill_viridis(discrete = TRUE, direction = -1) +
  guides(fill = guide_legend(nrow = 2))

Modèle à observations répétées

Pour prendre en considération l’ensemble des observations présentes (sans se limiter aux individus observés au moins sur une certaine période), nous pouvons avoir recours à un modèle à observations répétées.

Il s’agit de modèles classiques sauf qu’au lieu de considérer une ligne par individu, nous allons intégrer dans le modèle une ligne par individu et par pas de temps. Dans la mesure où nous avons plusieurs observations pour une même personne, cela doit être pris en compte par l’ajout d’un effet aléatoire dans le cadre d’un modèle mixte ou en ayant recours à un (voir le chapitre sur les modèles à effets aléatoires).

Vue la nature de notre variable d’intérêt (plusieurs modalités ordonnées), nous aurons recours à une régression logistique ordinale (voir le chapitre dédié). Pour un modèle mixte ordinal on peut utiliser la fonction clmm de l’extension ordinal. Pour un modèle GEE ordinal, citons ordgee de l’extension geepack ou encore ordLORgee de multgee. Il importe également que la dimension temporelle soit inclue dans les variables du modèle.

Ici, nous allons utiliser ordgee. Il nous faut tout d’abord transformer notre variable d’intérêt en un facteur ordonné.

care_trajectories[, care_statusF := to_factor(care_status, ordered = TRUE)]

Nous allons transformer nos variables explicatives en facteurs. Pour le temps, dans la mesure où sont effet n’est pas forcément linéaire, nous allons l’intégrer en tant que variable catégorielle. Par contre, comme nous n’avons que très peu d’observations individuelles après 3 ans, nous ne prendrons en compte que les observations des 36 premiers mois. Nous allons aussi retirer les observations à M0 puisqu’à ce moment précis tous les individus sont dans la même situation (diagnostiqués mais pas en soins.)

ct36 <- care_trajectories[month > 0 & month <= 36, ]
ct36[, sexF := to_factor(sex)]
ct36[, ageF := to_factor(age)]
ct36[, educationF := to_factor(education)]
ct36[, monthF := to_factor(month)]

Calculons notre modèle.

library(geepack)
mod_td <- ordgee(
  care_statusF ~ sexF + ageF + educationF + monthF,
  data = ct36,
  id = ct36$id
)

Les coefficients du modèle s’obtiennent avec summary. Malheureusement, il n’existe pas de tieder pour ce type de modèle. Nous allons donc procéder manuellement.

res <- summary(mod_td)$mean
res$term <- rownames(res)
head(res)
estimate san.se wald p term
Inter:diagnostiqué, mais pas suivi -2.8569848 0.1272376 504.17899 0.0000000 Inter:diagnostiqué, mais pas suivi
Inter:suivi, mais pas sous traitement -3.4247822 0.1289357 705.53705 0.0000000 Inter:suivi, mais pas sous traitement
Inter:sous traitement, mais infection non contrôlée -3.9464056 0.1320344 893.36522 0.0000000 Inter:sous traitement, mais infection non contrôlée
sexFfemme 0.7419722 0.0867777 73.10695 0.0000000 sexFfemme
ageF30-59 0.5576609 0.0890031 39.25822 0.0000000 ageF30-59
ageF60+ 0.7147037 0.1930243 13.70970 0.0002133 ageF60+

Les intervalles de confiance à 95% ne sont pas déjà calculés. Faisons-le donc nous même.

mult <- stats::qnorm((1 + .95) / 2)
res$conf.low <- res$estimate - mult * res$san.se
res$conf.high <- res$estimate + mult * res$san.se

Enfin, nous souhaitons disposer des odds ratios et non des coefficients bruts. Il faut avoir recours à la fonction exp (exponentielle).

res$estimate <- exp(res$estimate)
res$conf.low <- exp(res$conf.low)
res$conf.high <- exp(res$conf.high)

Préparons un tableau avec les résultats. Pour le rendre plus lisible, nous allons mettre en forme les odds ratios avec une seule décimale. Améliorer le rendu des p-values et nous allons utiliser la virgule comme séparateur de décimal, comme il se doit. Nous aurons recours aux fonctions number et pvalue de l’extension scales (voir le chapitre sur la mise en forme des nombres).

tab <- res %>% 
  mutate (
    estimate = scales::number(estimate, accuracy = .01, decimal.mark = ","),
    p = scales::pvalue(p, decimal.mark = ","),
    conf.low = scales::number(conf.low, accuracy = .1, decimal.mark = ","),
    conf.high = scales::number(conf.high, accuracy = .1, decimal.mark = ",")
  ) %>%
  dplyr::select(
    Facteur = term, OR = estimate, "p-value" = p, 
    "IC 95% bas" = conf.low, "IC 95% haut" = conf.high
  )
knitr::kable(tab, row.names = FALSE, align = "lrrrr")
Facteur OR p-value IC 95% bas IC 95% haut
Inter:diagnostiqué, mais pas suivi 0,06 <0,001 0,0 0,1
Inter:suivi, mais pas sous traitement 0,03 <0,001 0,0 0,0
Inter:sous traitement, mais infection non contrôlée 0,02 <0,001 0,0 0,0
sexFfemme 2,10 <0,001 1,8 2,5
ageF30-59 1,75 <0,001 1,5 2,1
ageF60+ 2,04 <0,001 1,4 3,0
educationFsecondaire 1,17 0,109 1,0 1,4
educationFsupérieur 1,40 0,002 1,1 1,7
monthF2 1,06 0,147 1,0 1,1
monthF3 1,36 <0,001 1,2 1,5
monthF4 2,79 <0,001 2,5 3,1
monthF5 3,82 <0,001 3,4 4,3
monthF6 4,69 <0,001 4,1 5,4
monthF7 5,63 <0,001 4,9 6,4
monthF8 6,40 <0,001 5,6 7,3
monthF9 7,02 <0,001 6,1 8,1
monthF10 7,49 <0,001 6,5 8,6
monthF11 7,96 <0,001 6,9 9,2
monthF12 8,42 <0,001 7,3 9,8
monthF13 9,31 <0,001 8,0 10,8
monthF14 10,11 <0,001 8,6 11,8
monthF15 10,74 <0,001 9,2 12,6
monthF16 11,46 <0,001 9,8 13,4
monthF17 11,43 <0,001 9,7 13,4
monthF18 11,53 <0,001 9,8 13,6
monthF19 11,50 <0,001 9,7 13,6
monthF20 11,70 <0,001 9,7 14,1
monthF21 11,67 <0,001 9,6 14,2
monthF22 12,60 <0,001 10,3 15,4
monthF23 12,78 <0,001 10,4 15,7
monthF24 12,76 <0,001 10,4 15,7
monthF25 13,11 <0,001 10,6 16,2
monthF26 13,60 <0,001 11,0 16,9
monthF27 14,40 <0,001 11,6 17,9
monthF28 15,65 <0,001 12,5 19,6
monthF29 14,89 <0,001 11,9 18,7
monthF30 14,98 <0,001 11,9 18,9
monthF31 14,02 <0,001 11,0 17,9
monthF32 14,27 <0,001 11,0 18,5
monthF33 14,41 <0,001 11,0 18,9
monthF34 14,73 <0,001 11,0 19,7
monthF35 16,17 <0,001 11,8 22,1
monthF36 16,07 <0,001 11,4 22,6

On peut facilement représenter tout cela graphiquement. On va supprimer les termes seuils, grâce à str_detect de stringr. On notera le recours à fct_inorder de forcats pour conserver l’ordre des termes selon leur ordre d’apparition.

res <- res[!str_detect(res$term, "Inter"),]
res$term <- fct_inorder(res$term)
res$term <- fct_recode(res$term,
               "femme vs. homme" = "sexFfemme",
               "âge : 30-59 vs. 16-29" = "ageF30-59",
               "âge : 60+ vs 16-29" = "ageF60+",
               "éducation : secondaire vs. primaire" = "educationFsecondaire",
               "éducation : supérieure vs. primaire" = "educationFsupérieur",
               "M2" = "monthF2",
               "M3" = "monthF3",
               "M4" = "monthF4",
               "M5" = "monthF5",
               "M6" = "monthF6",
               "M7" = "monthF7",
               "M8" = "monthF8",
               "M9" = "monthF9",
               "M10" = "monthF10",
               "M11" = "monthF11",
               "M12" = "monthF12",
               "M13" = "monthF13",
               "M14" = "monthF14",
               "M15" = "monthF15",
               "M16" = "monthF16",
               "M17" = "monthF17",
               "M18" = "monthF18",
               "M19" = "monthF19",
               "M20" = "monthF20",
               "M21" = "monthF21",
               "M22" = "monthF22",
               "M23" = "monthF23",
               "M24" = "monthF24",
               "M25" = "monthF25",
               "M26" = "monthF26",
               "M27" = "monthF27",
               "M28" = "monthF28",
               "M29" = "monthF29",
               "M30" = "monthF30",
               "M31" = "monthF31",
               "M32" = "monthF32",
               "M33" = "monthF33",
               "M34" = "monthF34",
               "M35" = "monthF35",
               "M36" = "monthF36")
res$var_group <- c("a", "b", "b", "c", "c", rep("d", 35))

GGally::ggcoef(
    res, exponentiate = TRUE, 
    mapping = aes(x = estimate, y = fct_rev(term), color = var_group)
  ) +
  theme_classic() + ylab("") + xlab("Odds Ratio") +
  theme(legend.position = "none")

Sur ce graphique, on visualise bien l’évolution temporelle traduite par les odds ratios associés à chaque mois, ainsi que les effets globaux de nos covariables : les femmes ont une meilleure progression dans la cascade de soins que les hommes, de même que les plus éduqués et les plus âgés.

Modèle de survie multi-états

Depuis la fin du XXe siècle, de nombreux développements ont réalisés pour étendre les modèles de survie à des processus multi-états. Ces modèles permettent de considérer une grande variété de processus. Plusieurs implémentations existent dans R3. Ici, nous allons utiliser l’extension msm qui repose sur des modèles de Markov multi-états et peut prendre en compte des co-variables dans le modèle.

En premier lieu, pour cette extension, ils nous faut disposer des données sous une forme longue, c’est-à-dire avec une ligne par individu et point d’observation dans le temps, ce qui est déjà le cas du fichier care_trajectories. Les différents status possibles doivent également être codés sous la forme de nombres entiers croissants (ici 1 correspondra à D, 2 à C, 3 à T et 4 à S).

library(msm)
care_trajectories$status <- as.integer(to_factor(care_trajectories$care_status))
setorder(care_trajectories, id, month)

Par ailleurs, nous n’allons concerver dans l’analyse que les individus avec au moins deux points d’observation, ici ceux observés au moins jusqu’à un mois.

ct <- care_trajectories[id %in% care_trajectories[month == 1, id]]

La fonction statetable.msm permet de calculer le nombre et le type de transitions observées dans les données.

statetable.msm(status, id, data = ct)
from/to 1 2 3 4
1 21916 1168 467 247
2 501 4323 597 210
3 26 141 3489 770
4 33 230 43 12275

Il faut ensuite définir les transitions possibles dans le modèle en faisant une matrice carrée. On indiquera 0 si la transition n’est pas possible, une valeur positive sinon.

tr <- rbind(
  c(0, 1, 0, 0), # de 1 : vers 2
  c(1, 0, 1, 0), # de 2 : vers 1 ou vers 3
  c(0, 1, 0, 1), # de 3 : vers 2 ou vers 4
  c(0, 0, 1, 0)  # de 4 : vers 3
)

Dans notre matrice de transitions, nous n’avons pas défini de transition directe entre le statut 1 et le statut 3, alors que de telles transitions sont pourtant observées dans notre fichier. En fait, nous pouvons considérer qu’une transition de 1 vers 3 correspond en fait à deux transitions successives, de 1 vers 2 puis de 2 vers 3. La fonction msm s’aura identifier d’elle-mêmes ces doubles, voire triples, transitions.

On peut facilement représenter notre matrice de transition sous forme de schéma à l’aide de l’excellente extension DiagrammeR.

library(DiagrammeR)
mermaid("
graph TD
1[diagnostiqué, mais pas suivi]
2[suivi, mais pas sous traitement]
3[sous traitement, mais infection non contrôlée]
4[sous traitement et infection contrôlée]

1--entrée<br />en soins-->2
2--initiation<br />traitement-->3
2--sortie<br />de soins-->1
3--contrôle<br />infection-->4
3--arrêt<br />traitement-->2
4--échec<br/>virologique-->3
", height = 300)

Il ne nous reste plus qu’à spécifier notre modèle. L’option obstype = 1 indique à msm que nos données correspondent à des snapshots à certains moments donnés (ici tous les mois) et donc que les transitions d’un état à un autre ont eu lieu entre nos points d’observation. Les types 2 et 3 correspondent à des dates de transition exactes (voir l’aide la fonction pour plus de détails).

ms_mod <- msm(
  status ~ month, subject = id, data = ct, qmatrix = tr, obstype = 1
)

En exécutant cette commande, vous risquez d’obtenir le message d’erreur suivant :

Error in Ccall.msm(params, do.what = "lik", ...) : numerical overflow in calculating likelihood

Cela est dû à un problème d’échelle dans l’optimisation du modèle qui génère des nombres plus grands que ce que peux gérer l’ordinateur. Il peut être résolu de la manière suivante. Tout d’abord, on reexécute le modèle avec l’option control = list(trace = TRUE).

ms_mod <- msm(
  status ~ month, subject = id, data = ct, qmatrix = tr, obstype = 1, 
  control = list(trace = TRUE)
)

On obtient le message suivant :

initial  value 74796.800445 
Error in Ccall.msm(params, do.what = "lik", ...) : numerical overflow in calculating likelihood

Ce qui importe de retenir, c’est la valeur initiale du paramètre d’optimisation avant que l’erreur ne se produise. On va l’utiliser (ou une valeur proche) comme paramètre d’échelle pour l’optimation avec l’option fnscale :

ms_mod <- msm(
  status ~ month, subject = id, data = ct, qmatrix = tr, obstype = 1, 
  control = list(fnscale = 75000, trace = TRUE)
)
initial  value 0.997291 
iter  10 value 0.520302
iter  20 value 0.497598
iter  30 value 0.497487
final  value 0.497484 
converged
Used 39 function and 37 gradient evaluations

On peut comparer la prévalence dans chaque état au cours du temps telle que modélisée par le modèle avec les valeurs observées avec la fonction plot.prevalence.msm.

plot.prevalence.msm(ms_mod)

Par défaut, msm considère que les intensités de transition d’un état à un autre sont constantes au cours du temps. Or, dans notre example, il apparait que les prévalences observées varient différemment pendant les premiers mois après le diagnostic. Nous allons donc recalculer le modèle en spécifiant avec le paramètre pci que nous souhaitons considérer des intensités de transition différentes pour les trois premiers mois, la première année, la seconde année et après la seconde année. Comme il faudra plus d’itérations pour faire converger notre modèle, nous avons également augmenter la valeur du paramètre maxit (100 par défaut).

ms_mod <- msm(
  status ~ month, subject = id, data = ct, qmatrix = tr, obstype = 1, 
  pci = c(3, 12, 24),
  control = list(fnscale = 75000, trace = TRUE, maxit = 500)
)

Comparons à nouveau les prévalences estimées avec les prévalences observées.

plot.prevalence.msm(ms_mod)

Comme on peut le voir, l’ajustement entre les deux a été amélioré. Les prévalences elles-mêmes peuvent s’obtenir avec prevalence.msm.

prevalence.msm(ms_mod)
$Observed
   State 1 State 2 State 3 State 4 Total
0     2799      24       0       7  2830
5     1551     292     297     460  2600
10     958     257     210     623  2048
15     578     168     104     603  1453
20     283      87      65     327   762
25     192      63      39     267   561
30     147      41      23     245   456
35      69      17      12     136   234
40      14       2       2      27    45
45       7       0       0      12    19
50       0       0       0       1     1

$Expected
        State 1      State 2      State 3     State 4 Total
0  2799.0000000  24.00000000   0.00000000   7.0000000  2830
5  1436.9517812 424.94481382 358.54921455 379.5541904  2600
10 1017.4844830 258.18412962 191.08425368 581.2471337  2048
15  667.5131754 168.10101158  98.36234055 519.0234724  1453
20  331.9787922  81.73411456  46.82691929 301.4601739   762
25  233.1379082  55.54030396  32.92027747 239.4015104   561
30  184.4057933  40.32826279  24.41822743 206.8477165   456
35   91.3576268  19.57230370  12.12106094 110.9490085   234
40   16.9423183   3.63904521   2.30424907  22.1143875    45
45    6.9062654   1.49869230   0.96896925   9.6260731    19
50    0.3515898   0.07725341   0.05092087   0.5202359     1

$`Observed percentages`
    State 1    State 2   State 3     State 4
0  98.90459  0.8480565  0.000000   0.2473498
5  59.65385 11.2307692 11.423077  17.6923077
10 46.77734 12.5488281 10.253906  30.4199219
15 39.77977 11.5622849  7.157605  41.5003441
20 37.13911 11.4173228  8.530184  42.9133858
25 34.22460 11.2299465  6.951872  47.5935829
30 32.23684  8.9912281  5.043860  53.7280702
35 29.48718  7.2649573  5.128205  58.1196581
40 31.11111  4.4444444  4.444444  60.0000000
45 36.84211  0.0000000  0.000000  63.1578947
50  0.00000  0.0000000  0.000000 100.0000000

$`Expected percentages`
    State 1    State 2   State 3    State 4
0  98.90459  0.8480565  0.000000  0.2473498
5  55.26738 16.3440313 13.790354 14.5982381
10 49.68186 12.6066470  9.330286 28.3812077
15 45.94034 11.5692369  6.769604 35.7208171
20 43.56677 10.7262618  6.145265 39.5617026
25 41.55756  9.9002324  5.868142 42.6740660
30 40.43987  8.8439173  5.354874 45.3613413
35 39.04172  8.3642323  5.179941 47.4141062
40 37.64960  8.0867671  5.120553 49.1430833
45 36.34877  7.8878542  5.099838 50.6635426
50 35.15898  7.7253409  5.092087 52.0235901

Ceci dit, le format dans lequel sont renvoyées les prévalences n’est que peu pratique pour les exploiter ensuite, par exemple avec ggplot2. L’extension JLutils fournit une fonction expérimentale tidy.prevalence.msm4 permettant de transformer ce résultat dans un format tidy.

library(JLutils)
prev <- tidy.prevalence.msm(prevalence.msm(ms_mod, times = 0:36))
head(prev)
time status observed expected observed.percentage expected.percentage
0 State 1 2799 2799.000 98.90459 98.90459
1 State 1 1942 2329.479 68.62191 82.31374
2 State 1 1766 1905.419 63.54804 68.56490
3 State 1 1651 1552.664 60.76555 57.14627
4 State 1 1589 1500.043 59.58005 56.24458
5 State 1 1551 1436.952 59.65385 55.26738
prev$status <- to_factor(prev$status)
casc_status <- c(
  "diagnostiqué, mais pas suivi",
  "suivi, mais pas sous traitement",
  "sous traitement, mais infection non contrôlée",
  "sous traitement et infection contrôlée"
)
levels(prev$status) <- casc_status

Il est alors ensuite facile de produire le graphique de la cascade de soins, estimée par le modèle, que l’on pourra mettre en comparaison de la cascade observée que nous avions calculé tout à l’heure.

casc_est <- ggplot(prev) +
  aes(x = time, fill = status, weight = expected) +
  geom_bar(color = "gray50", width = 1, position = "fill") +
  scale_x_continuous(breaks = 0:6*6, labels = paste0("M", 0:6*6)) +
  scale_y_continuous(labels = scales::percent) +
  ggtitle("Cascade des soins estimée, selon le temps depuis le diagnostic") +
  xlab("") + ylab("") +
  theme_light() +
  theme(legend.position = "bottom") +
  labs(fill = "Statut dans les soins") + 
  scale_fill_viridis(discrete = TRUE, direction = -1) +
  guides(fill = guide_legend(nrow = 2))
multiplot(casc_obs, casc_est)

Comme on peut le voir, dans le modèle, l’évolution est plus lissée comparativement aux données brutes observées.

Un des intérêts de msm est la possibilité d’y intégrer des covariables, permettant ainsi de calculer un modèle multivarié. Les variables peuvent être dépendantes du temps, puisqu’il suffit de renseigner leur valeur à chaque point d’observation.

ct$sex <- to_factor(ct$sex)
ct$age <- to_factor(ct$age)
ct$education <- to_factor(ct$education)
ms_mod_mult <- msm(
  status ~ month, subject = id, data = ct, qmatrix = tr, obstype = 1, 
  pci = c(3, 12, 24),
  control = list(fnscale = 75000, trace = TRUE, maxit = 500),
  covariates = ~ sex + age + education
)

Les risques relatifs, ou hazard ratios en anglais, associés à chaque covariable et à chaque transition s’obtiennent avec hazard.msm. Une fois encore, le format de sortie n’est pas le plus adapté pour un traitement graphique, mais on pourra avoir recours à tidy.hazard.msm de JLutils.

hr <- tidy.hazard.msm(hazard.msm(ms_mod_mult))
head(hr)
term transition from to estimate conf.low conf.high
sexfemme State 1 - State 2 State 1 State 2 1.8855232 1.7059612 2.083985
sexfemme State 2 - State 1 State 2 State 1 0.9245660 0.7655997 1.116540
sexfemme State 2 - State 3 State 2 State 3 0.9015913 0.8044458 1.010468
sexfemme State 3 - State 2 State 3 State 2 1.0959810 0.8854966 1.356498
sexfemme State 3 - State 4 State 3 State 4 1.3985443 1.2300980 1.590057
sexfemme State 4 - State 3 State 4 State 3 0.8610144 0.6678918 1.109979

On va recoder certaines étiquettes en vue de faire un graphique des résultats.

hr$type <- "Transition ascendante"
hr[hr$transition == c("State 2 - State 1"),]$type <- "Transition descendante"
hr[hr$transition == c("State 3 - State 2"),]$type <- "Transition descendante"
hr[hr$transition == c("State 4 - State 3"),]$type <- "Transition descendante"

hr$term <- fct_recode(
  fct_inorder(hr$term),
  "femme vs. homme" = "sexfemme",
  "30-59 vs. 16-29" = "age30-59",
  "60+ vs. 16-29" = "age60+",
  "éduc. secondaire vs. primaire" = "educationsecondaire",
  "éduc. supérieure vs. primaire" = "educationsupérieur"
)

hr$transition <- fct_recode(
  fct_inorder(hr$transition),
  "entrée en soins" = "State 1 - State 2",
  "sortie de soins" = "State 2 - State 1",
  "initiation traitement" = "State 2 - State 3",
  "arrêt traitement" = "State 3 - State 2",
  "contrôle infection" = "State 3 - State 4",
  "échec virologique" = "State 4 - State 3"
)

head(hr)
term transition from to estimate conf.low conf.high type
femme vs. homme entrée en soins State 1 State 2 1.8855232 1.7059612 2.083985 Transition ascendante
femme vs. homme sortie de soins State 2 State 1 0.9245660 0.7655997 1.116540 Transition descendante
femme vs. homme initiation traitement State 2 State 3 0.9015913 0.8044458 1.010468 Transition ascendante
femme vs. homme arrêt traitement State 3 State 2 1.0959810 0.8854966 1.356498 Transition descendante
femme vs. homme contrôle infection State 3 State 4 1.3985443 1.2300980 1.590057 Transition ascendante
femme vs. homme échec virologique State 4 State 3 0.8610144 0.6678918 1.109979 Transition descendante

Vu le nombre de coefficients (un risque relatif par covariable et par transition), on va organiser le graphique en distinguant les transitions acsendantes et les transitions descendantes, d’une part, et en regroupant les risques relatifs d’une même covariable, d’autre part. Pour alléger le graphique, nous allons également retirer la covariable timeperiod créé par l’argument pci, en ayant recours à str_detect de l’extension stringr pour repérer les lignes en questions (voir le chapitre sur la manipulation de texte).

ggplot(data = hr[!str_detect(hr$term, "time"), ]) +
  aes(
    x = fct_rev(term), y = estimate, color = fct_rev(transition),
    ymin = conf.low, ymax = conf.high 
  ) +
  geom_hline(yintercept = 1, color = "gray25", linetype = "dotted") +
  geom_errorbar(position = position_dodge(0.5), width = 0) +
  geom_point(position = position_dodge(0.5)) + 
  scale_y_log10() + 
  facet_grid(~ type) +
  coord_flip() +
  theme_classic() +
  theme(legend.position = "bottom") +
  ylab("risque relatif") + xlab("") +
  labs(color = "Transition") +
  scale_color_brewer(palette = "Paired") +
  guides(color = guide_legend(reverse = TRUE))

Ce modèle de survie multi-états permet de mettre en évidence des effets différenciés selon la transition considérée. Par exemple, les femmes sont plus rapides en matière d’entrée en soins et de contrôle de l’infection (une fois le traitement initié) mais plus lentes à démarrer le traitement (une fois entrées en soins). Par contre, le sexe ne semble pas jouer sur les transitions descendantes (échec virologique, arrête du traitement ou sortie de soins).


  1. Pour plus de détails sur les tableaux croisés et le test du Chi², voir le chapitre sur la statisque bivariée et le chapitre sur les tests de comparaison.

  2. À noter, ggbivariate accepte également des variables continues.

  3. Comme par exemple msSurv pour une estimation non-paramétrique.

  4. avant l’éventuelle intégration diretement dans msm d’un tidier officiel.

Analyse de réseaux

Un bon tutoriel pour s’initier à la visualisation des réseaux avec R, Network visualization with R de Katherine Ognyanova, est disponible en ligne : http://kateto.net/network-visualization.

On pourra poursuivre avec différents billets de blog publiés par François Briatte sur https://politbistro.hypotheses.org/. Enfin, François Briatte a également recensé de nombreuses ressources en ligne sur l’analyse de réseau dans son An awesome list of network analysis resources (http://f.briatte.org/r/awesome-network-analysis-list).

Analyse spatiale

Il est tout à fait possible de réaliser des analyses spatiales sous R. Historiquement, l’extension principale pour la gestion des objets spatiaux sous R est l’extension sp. Depuis quelques années, une nouvelle extension sf s’est développée. Alors, faut-il plutôt apprendre sp ou sf ? Chris Brown tente de répondre à cette question dans son billet Should I learn sf or sp for spatial R programming?. Ces deux extensions ont leurs avantages et inconvénients. Du fait que sp est plus ancienne, elle est compatible avec plus d’autres extensions. De l’autre côté, sf peut s’avérer plus simple pour le néophyte. Dans tous les cas, l’extension raster sera un bon complément pour gérer les données de type raster.

Pour une présentation détaillée (en anglais) de l’analyse spatiale sous R, on pourra se référer à l’ouvrage Geocomputation with R de Robin Lovelace, Jakub Nowosad et Jannes Muenchow, consultable en ligne (https://geocompr.robinlovelace.net/). Cette ouvrage privilégie plutôt l’extension sf.

On pourra également se référer aux différentes vignettes inclues par leurs extensions et consultables en ligne sur :

Pour la réalisation de cartes avec R, on pourra se référer au chapitre dédié.

Enfin, le site Awesome R fournit une sélection d’extensions dédiées à l’analyse spatiale.

ggplot2 et la grammaire des graphiques

Ce chapitre est en cours d’écriture.

On pourra se référer au chapitre 5 Graphiques du support de cours d’Ewen Gallic intitulé Logiciel R et programmation (http://egallic.fr/Enseignement/R/m1_stat_eco_logiciel_R.pdf), en complément des deux chapitres introductifs d’analyse-R : introduction à ggplot2 et graphiques bivariés avec ggplot2.

Grammaire des graphiques de ggplot2

Ouvrages

  • ggplot2: Elegant Graphics for Data Analysis (Use R!) d’Hadley Wickham 1
  • R Graphics Cookbook de Winston Chang

Assistants pour ggplot2

Plusieurs extensions propose une assistance visuelle pour l’utilisation de ggplot2 via des add-ins dans RStudio :

Étendre ggplot2

De nombreuses extensions permettent d’étendre les possibilités graphiques de ggplot2. Certaines ont déjà été abordées dans les différents chapitres d’analyse-R. Le présent chapitre ne se veut pas exhaustif et ne présente qu’une sélection choisie d’extensions.

Le site ggplot2 extensions (https://exts.ggplot2.tidyverse.org/gallery/) recense diverses extensions pour ggplot2.

Pour une présentation des fonctions de base et des concepts de ggplot2, on pourra se référer au chapitre dédié ainsi qu’au deux chapitres introductifs : introduction à ggplot2 et graphiques bivariés avec ggplot2.

Pour trouver l’inspiration et des exemples de code, rien ne vaut l’excellent site https://www.r-graph-gallery.com/.

Nouvelles géométries

Étiquettes non superposées

Lorsque l’on affiche des étiquettes de texte, ces dernières peuvent se supperposer lorsqu’elles sont proches. Les géométries geom_text_repel et geom_label_repel de l’extension ggrepel prennent en compte la position des différentes étiquettes pour éviter qu’elles ne se chevauchent.

library(ggplot2)
library(ggrepel)
library(ggrepel)

dat <- subset(mtcars, wt > 2.75 & wt < 3.45)
dat$car <- rownames(dat)
p <- ggplot(dat) +
  aes(wt, mpg, label = car) +
  geom_point(color = "red")

p1 <- p + geom_text() +
  labs(title = "geom_text()")
p2 <- p + geom_text_repel() +
  labs(title = "geom_text_repel()")

cowplot::plot_grid(p1, p2, nrow = 1)

Pour plus d’informations : https://ggrepel.slowkow.com/

Graphiques en sucettes (lollipop)

L’extension ggalt propose une géométrie geom_lollipop permettant de réaliser des graphiques dit en sucettes.

df <- read.csv(text = "category,pct
Other,0.09
South Asian/South Asian Americans,0.12
Interngenerational/Generational,0.21
S Asian/Asian Americans,0.25
Muslim Observance,0.29
Africa/Pan Africa/African Americans,0.34
Gender Equity,0.34
Disability Advocacy,0.49
European/European Americans,0.52
Veteran,0.54
Pacific Islander/Pacific Islander Americans,0.59
Non-Traditional Students,0.61
Religious Equity,0.64
Caribbean/Caribbean Americans,0.67
Latino/Latina,0.69
Middle Eastern Heritages and Traditions,0.73
Trans-racial Adoptee/Parent,0.76
LBGTQ/Ally,0.79
Mixed Race,0.80
Jewish Heritage/Observance,0.85
International Students,0.87", stringsAsFactors = FALSE, sep = ",", header = TRUE)

library(ggplot2)
library(ggalt)
library(scales)

ggplot(df) +
  aes(y = reorder(category, pct), x = pct) +
  geom_lollipop(point.colour = "steelblue", point.size = 2, horizontal = TRUE) +
  scale_x_continuous(expand = c(0, 0), labels = percent, breaks = seq(0, 1, by = 0.2), limits = c(0, 1)) +
  labs(
    x = NULL, y = NULL,
    title = "SUNY Cortland Multicultural Alumni survey results",
    subtitle = "Ranked by race, ethnicity, home land and orientation\namong the top areas of concern",
    caption = "Data from http://stephanieevergreen.com/lollipop/"
  ) +
  theme_minimal()

Graphique d’haltères (dumbbell)

L’extension ggalt propose une géométrie geom_dumbbell permettant de réaliser des graphiques dit en haltères.

library(ggalt)
df <- data.frame(
  trt = LETTERS[1:5],
  l = c(20, 40, 10, 30, 50),
  r = c(70, 50, 30, 60, 80)
)

ggplot(df) +
  aes(y = trt, x = l, xend = r) +
  geom_dumbbell(
    size = 3,
    color = "#e3e2e1",
    colour_x = "#5b8124",
    colour_xend = "#bad744"
  ) +
  labs(x = NULL, y = NULL) +
  theme_minimal()

Accolades de comparaison (bracket)

La géométrie geom_braket de l’extension ggpubr permets d’ajouter sur un graphique des accolades de comparaison entre groupes.

library(ggpubr)
df <- ToothGrowth
df$dose <- factor(df$dose)

ggplot(df) +
  aes(x = dose, y = len) +
  geom_boxplot() +
  geom_bracket(
    xmin = "0.5", xmax = "1", y.position = 30,
    label = "t-test, p < 0.05"
  )

ggplot(df) +
  aes(x = dose, y = len) +
  geom_boxplot() +
  geom_bracket(
    xmin = c("0.5", "1"),
    xmax = c("1", "2"),
    y.position = c(30, 35),
    label = c("***", "**"),
    tip.length = 0.01
  )

Plus d’informations : https://rpkgs.datanovia.com/ggpubr/

Diagramme en crêtes (ridges)

L’extension ggridges fournit une géométrie geom_density_ridges_gradient pour la création de diagramme en crêtes.

library(ggridges)
ggplot(lincoln_weather, aes(x = `Mean Temperature [F]`, y = Month, fill = stat(x))) +
  geom_density_ridges_gradient(scale = 3, rel_min_height = 0.01) +
  scale_fill_viridis_c(name = "Temp. [F]", option = "C") +
  labs(title = "Temperatures in Lincoln NE in 2016") +
  theme_ridges()
Picking joint bandwidth of 3.37

Plus d’informations : https://wilkelab.org/ggridges/

Graphique en gaufres (waffle)

L’extension waffle propose geom_waffle pour des graphiques dits en gaufres.

ATTENTION : elle s’installe avec la commande install.packages("waffle", repos = "https://cinc.rud.is").

library(waffle)
xdf <- data.frame(
  parts = factor(rep(month.abb[1:3], 3), levels = month.abb[1:3]),
  vals = c(10, 20, 30, 6, 14, 40, 30, 20, 10),
  fct = c(rep("Thing 1", 3), rep("Thing 2", 3), rep("Thing 3", 3))
)

ggplot(xdf) +
  aes(fill = parts, values = vals) +
  geom_waffle() +
  facet_wrap(~fct) +
  scale_fill_manual(
    name = NULL,
    values = c("#a40000", "#c68958", "#ae6056"),
    labels = c("Fruit", "Sammich", "Pizza")
  ) +
  coord_equal() +
  theme_minimal() +
  theme_enhance_waffle()

Plus d’informations : https://github.com/hrbrmstr/waffle

Graphique en mosaïque (mosaic plot)

L’extension ggmosaic permets de réaliser des graphiques en mosaïque avec geom_mosaic.

library(ggmosaic)
ggplot(data = fly) +
  geom_mosaic(
    aes(x = product(RudeToRecline), fill = RudeToRecline),
    na.rm = TRUE
  )

ggplot(data = fly) +
  geom_mosaic(
    aes(x = product(DoYouRecline, RudeToRecline), fill = DoYouRecline),
    na.rm = TRUE
  )

Plus d’informations : https://cran.r-project.org/web/packages/ggmosaic/vignettes/ggmosaic.html

Graphique de pirates : alternative aux boîtes à moustache (pirat plot)

Cette représentation alternative aux boîtes à moustache s’obtient avec la géométrie geom_pirate de l’extension ggpirate1.

library(ggplot2)
library(ggpirate)
ggplot(mpg, aes(x = class, y = cty)) +
  geom_pirate(aes(colour = class, fill = class)) +
  theme_bw()

Pour plus d’informations : https://github.com/mikabr/ggpirate

Axes, légende et facettes

Axes limités

coord_capped_cart et coord_capped_flip de l’extension lemon permet de limiter le dessin des axes au minimum et au maximum. Voir l’exemple ci-dessous.

library(ggplot2)
library(lemon)
p <- ggplot(mtcars) +
  aes(x = cyl, y = mpg) +
  geom_point() +
  theme_classic() +
  ggtitle("Axes classiques")
pcapped <- p +
  coord_capped_cart(bottom = "both", left = "both") +
  ggtitle("Axes limités")
cowplot::plot_grid(p, pcapped, nrow = 1)

Répéter les étiquettes des axes sur des facettes

Lorsque l’on réalise des facettes, les étiquettes des axes ne sont pas répétées.

library(ggplot2)
ggplot(mpg) +
  aes(displ, cty) +
  geom_point() +
  facet_wrap(~cyl)

L’extension lemon propose facet_rep_grid et facet_rep_wrap qui répètent les axes sur chaque facette.

library(lemon)
ggplot(mpg) +
  aes(displ, cty) +
  geom_point() +
  facet_rep_wrap(~cyl, repeat.tick.labels = TRUE)

Cartes

Voir le chapitre dédié.

Graphiques complexes

Graphiques divergents

L’extension ggcharts fournit plusieurs fonctions de haut niveau pour faciliter la réalisation de graphiques divergents en barres (diverging_bar_chart), en sucettes (diverging_lollipop_chart) voire même une pyramide des âges (pyramid_chart).

library(ggcharts)
data(mtcars)
mtcars_z <- dplyr::transmute(
  .data = mtcars,
  model = row.names(mtcars),
  hpz = scale(hp)
)

diverging_bar_chart(data = mtcars_z, x = model, y = hpz)

diverging_lollipop_chart(
  data = mtcars_z,
  x = model,
  y = hpz,
  lollipop_colors = c("#006400", "#b32134"),
  text_color = c("#006400", "#b32134")
)

data("popch")
pyramid_chart(data = popch, x = age, y = pop, group = sex)
Warning: `expand_scale()` is deprecated; use `expansion()`
instead.

Warning: `expand_scale()` is deprecated; use `expansion()`
instead.

Warning: `expand_scale()` is deprecated; use `expansion()`
instead.

Warning: `expand_scale()` is deprecated; use `expansion()`
instead.

Graphiques interactifs

Voir le chapitre dédie.

Graphiques animés

L’extension gganimate permets de réaliser des graphiques animés.

Voici un exemple :

library(ggplot2)
library(gganimate)
library(gapminder)

ggplot(gapminder, aes(gdpPercap, lifeExp, size = pop, colour = country)) +
  geom_point(alpha = 0.7, show.legend = FALSE) +
  scale_colour_manual(values = country_colors) +
  scale_size(range = c(2, 12)) +
  scale_x_log10() +
  facet_wrap(~continent) +
  # Here comes the gganimate specific bits
  labs(title = "Year: {frame_time}", x = "GDP per capita", y = "life expectancy") +
  transition_time(year) +
  ease_aes("linear")

Voir le site de l’extension (https://gganimate.com/) pour la documentation et des tutoriels. Il est conseillé d’installer également l’extension gifski avec gganimate.

Surligner certaines données

L’extension gghighlight fournit une fonction gghiglight qui permets de surligner les données qui remplissent des conditions spécifiées.

d <- purrr::map_dfr(
  letters,
  ~ data.frame(
    idx = 1:400,
    value = cumsum(runif(400, -1, 1)),
    type = .,
    flag = sample(c(TRUE, FALSE), size = 400, replace = TRUE),
    stringsAsFactors = FALSE
  )
)

ggplot(d) +
  aes(x = idx, y = value, colour = type) +
  geom_line()

library(gghighlight)
ggplot(d) +
  aes(x = idx, y = value, colour = type) +
  geom_line() +
  gghighlight(max(value) > 20)
label_key: type

ggplot(iris, aes(Sepal.Length, fill = Species)) +
  geom_histogram() +
  gghighlight() +
  facet_wrap(~Species)

Thèmes et couleurs

Palettes de couleurs

Voir le chapitre Couleurs et palettes pour une sélection d’extensions proposant des palettes de couleurs additionnelles.

hrbrthemes

L’extension hrbrthemes fournit plusieurs thèmes graphiques pour ggplot2. Un exemple ci-dessous. Pour plus d’informations, voir https://github.com/hrbrmstr/hrbrthemes.

library(ggplot2)
library(hrbrthemes)
ggplot(mtcars, aes(mpg, wt)) +
  geom_point(aes(color = factor(carb))) +
  labs(
    x = "Fuel efficiency (mpg)", y = "Weight (tons)",
    title = "Seminal ggplot2 scatterplot example",
    subtitle = "A plot that is only useful for demonstration purposes",
    caption = "Brought to you by the letter 'g'"
  ) +
  scale_color_ipsum() +
  theme_ipsum_rc()

ggthemes

ggthemes propose une vingtaine de thèmes différentes présentés sur le site de l’extension : https://jrnold.github.io/ggthemes/.

Voir ci-dessous un exemple du thème theme_tufte inspiré d’Edward Tufte.

library(ggplot2)
library(ggthemes)

p <- ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point() +
  scale_x_continuous(breaks = extended_range_breaks()(mtcars$wt)) +
  scale_y_continuous(breaks = extended_range_breaks()(mtcars$mpg)) +
  ggtitle("Cars")

p + geom_rangeframe() +
  theme_tufte()

p + geom_rug() +
  theme_tufte(ticks = FALSE)

Combiner plusieurs graphiques

Voir le chapitre dédié.


  1. Cette extension n’étant pas sur CRAN, on l’installera avec la commande devtools::install_github("mikabr/ggpirate").

Combiner plusieurs graphiques

Vous savez réaliser des graphiques avec ggplot2 ? Il est très facile de combiner plusieurs graphiques en un seul.

multiplot (JLutils)

Dans son ouvrage Cookbook for R, Winston Chang propose une fonction multiplot pour combiner plusieurs graphiques1

L’extension JLutils disponible sur GitHub propose une version améliorée de cette fonction.

Pour installer JLutils si non disponible sur votre PC, copier/coller le code ci-dessous.

if (!require(devtools)) {
  install.packages("devtools")
  library(devtools)
}
install_github("larmarange/JLutils")

Commençons par créer quelques graphiques avec ggplot2.

library(ggplot2)
p1 <- ggplot(mtcars, aes(wt, mpg)) +
  geom_point()
p2 <- ggplot(mtcars, aes(factor(cyl))) +
  geom_bar()
p3 <- ggplot(mtcars, aes(factor(cyl), mpg)) +
  geom_violin()
p4 <- ggplot(mtcars, aes(factor(cyl), mpg)) +
  geom_boxplot()

Parce que quelques exemples valent mieux qu’un long discours.

library(JLutils)
multiplot(p1, p2, p3, p4)

multiplot(p1, p2, p3, p4, cols = 2)

multiplot(p1, p2, p3, layout = matrix(c(1, 2, 3, 3), nrow = 2))

multiplot(p1, p2, p3, layout = matrix(c(1, 2, 3, 3), nrow = 2, byrow = TRUE))

multiplot(p1, p2, p3, layout = matrix(c(1, 2, 3, 3), nrow = 2, byrow = TRUE), heights = c(3, 1))

plot_grid (cowplot)

L’extension cowplot propose une fonction équivalente, plot_grid. Son usage est expliqué en détail dans la vignette dédiée inclue avec l’extension : https://cran.r-project.org/web/packages/cowplot/vignettes/plot_grid.html.

library(cowplot)
# simple grid
plot_grid(p1, p2, p3, p4)

# simple grid with labels and aligned plots
plot_grid(p1, p2, p3, p4, labels = c("A", "B", "C", "D"), align = "hv")

# manually setting the number of rows, auto-generate upper-case labels
plot_grid(p1, p2, p3, nrow = 3, labels = "AUTO", label_size = 12, align = "v")

# making rows and columns of different widths/heights
plot_grid(p1, p2, p3, p4, align = "hv", rel_heights = c(2, 1), rel_widths = c(1, 2))

On notera en passant que le chargement de cowplot modifie le style par défaut des graphiques ggplot2. Voir https://cran.r-project.org/web/packages/cowplot/vignettes/introduction.html.

patchwork

Citons également l’extension patchwork, disponible sur GitHub (https://github.com/thomasp85/patchwork) qui propose une syntaxe un petit peu différente, par addition de graphiques.

library(patchwork)
p1 + (p2 + p3) + p4 + plot_layout(ncol = 1)

Légende partagée entre plusieurs graphiques

JLutils et cowplot fournissent tous deux une fonction get_legend permettant d’extraire la légende d’un graphique puis de l’utiliser avec multiplot ou plot_grid.

Créons quelques graphiques.

dsamp <- diamonds[sample(nrow(diamonds), 1000), ]
p1 <- qplot(carat, price, data = dsamp, colour = clarity) +
  theme(plot.margin = unit(c(6, 0, 6, 0), "pt"))
p2 <- qplot(depth, price, data = dsamp, colour = clarity) +
  theme(plot.margin = unit(c(6, 0, 6, 0), "pt")) + ylab("")
p3 <- qplot(color, price, data = dsamp, colour = clarity) +
  theme(plot.margin = unit(c(6, 0, 6, 0), "pt")) + ylab("")

Récupérons la légende du premier graphique graphique puis supprimons là dans les trois graphiques.

leg <- get_legend(p1)
p1 <- p1 + theme(legend.position = "none")
p2 <- p2 + theme(legend.position = "none")
p3 <- p3 + theme(legend.position = "none")

Combinons le tout.

multiplot(p1, p2, p3, leg, cols = 2)

plot_grid(p1, p2, p3, leg, ncol = 2)

Enfin, citons également la fonction grid_arrange_shared_legend de l’extension lemon2.


  1. Voir http://www.cookbook-r.com/Graphs/Multiple_graphs_on_one_page_(ggplot2)/.

  2. lemon fournit également diverses fonctions pour manipuler des graphiques ggplot2, comme par exemple la possibilité de répéter les axes quand on utilise des facettes.

Graphiques interactifs

ggplotly (plotly)

Vous savez réaliser des graphiques avec ggplot2 ? Vous savez faire un graphique interactif. Rien de plus facile avec la fonction ggplotly de l’extension plotly.

Créons un graphique.

library(ggplot2)
p <- ggplot(iris) +
  aes(x = Petal.Width, y = Sepal.Length, color = Species) +
  geom_point()

Voici son rendu classique avec ggplot2.

p

Et si on passe notre graphique à ggplotly. (N’hésitez pas à faire passer le curseur de votre souris sur le graphique.)

library(plotly)
ggplotly(p)

Une documentation complète sur ggplotly est disponible sur https://plot.ly/ggplot2/.

ggvis

Il existe également une extension ggvis dédiée aux graphiques interactifs. Sa documentation complète est disponible sur https://ggvis.rstudio.com/.

lattice : graphiques et formules

Bien que l’on ait fait le choix de présenter principalement l’extension ggplot2 plutôt que l’extension lattice, celle-ci reste un excellent choix pour la visualisation, notamment, de panels et de séries temporelles. On trouve de très beaux exemples d’utilisation de lattice en ligne, mais un peu moins de documentation, et beaucoup moins d’extensions, que pour ggplot2.

On peut trouver en ligne un support de cours détaillé (en anglais) de Deepayan Sarkar (https://www.isid.ac.in/~deepayan/R-tutorials/labs/04_lattice_lab.pdf), également l’auteur de l’ouvrage Lattice: Multivariate Data Visualization with R (http://lmdvr.r-forge.r-project.org/).

Les bases des graphiques lattice

R dispose de deux principaux systèmes graphiques : un système de base contrôlé par le package graphics et le système grid, sur lequel se basent à la fois les packages lattice et ggplot2. Ce système fournit les mêmes fonctionnalités de base que graphics mais offre une gestion de l’arrangement des objets graphiques plus développée, et surtout la possibilité d’utiliser ce que l’on appelle des graphiques en treillis. De plus, les graphiques peuvent être mis à jour très simplement, disposent de thèmes de couleur pré-définis, et offrent un certain degré d’interactivité, avec ou sans le package plotly. Enfin, la syntaxe est plus homogène et grandement simplifié, grâce à l’usage de formules.

De l’intérêt des formules R

Voici par exemple comment afficher la courbe de densité (i.e., la version continue et “lissée” d’un histogramme) de deux séries d’observations définies par les niveaux du facteur supp dans le data frame ToothGrowth, disponible dans les exemples de base de R. Notons que l’on souhaite également faire apparaître les distributions univariées, un peu à l’image de ce que fournit rug. Or cette fonction ne permet pas d’exploiter une variable de groupement, donc il sera nécessaire de gérer tout cela manuellement. Voici les instructions permettant de générer le graphique désiré :

plot(density(ToothGrowth$len[ToothGrowth$supp == "OJ"]), main = "", xlab = "len", las = 1, lwd = 2, col = "coral")
lines(density(ToothGrowth$len[ToothGrowth$supp == "VC"]), lwd = 2, col = "cornflowerblue")
points(
  x = ToothGrowth$len[ToothGrowth$supp == "OJ"],
  y = runif(length(ToothGrowth$len[ToothGrowth$supp == "OJ"]),
    min = -0.001, max = 0.001
  ), col = "coral"
)
points(
  x = ToothGrowth$len[ToothGrowth$supp == "VC"],
  y = runif(length(ToothGrowth$len[ToothGrowth$supp == "VC"]),
    min = -0.001, max = 0.001
  ), col = "cornflowerblue"
)
legend("top", levels(ToothGrowth$supp), col = c("coral", "cornflowerblue"), lty = 1, bty = "n")
Courbes de densité avec les graphiques de base

Il y a plusieurs points à retenir dans les instructions ci-dessus : (1) il est nécessaire de définir les deux courbes de densité et les deux distributions univariées, en prenant garde à bien indiquer comment sélectionner les observations (OJ ou VC) en préfixant systématiquement le nom des variables par le nom du data frame ; (2) la définition des couleurs se fait manuellement et si l’on souhaite changer de thème de couleur, il faudra mettre à jour l’ensemble des instructions, en prenant garde à ce que la lgende reste synchronisée avec les courbes de densité et les nuages de points ; et, bien entendu, (3) il est nécessaire de gérer soi-même la légende, ce qui signifie se rappeler les couleurs et l’ordre des niveaux du facteur considéré, ainsi que les axes graphiques dans le cas où l’on souhaite les maintenir coordonnés sur plusieurs panneaux graphiques.

Voici le même graphique avec lattice :

library(lattice)
densityplot(~len, data = ToothGrowth, group = supp, auto.key = TRUE)
Courbes de densité avec le package lattice

Avec ggplot2, cela donnerait :

library(ggplot2)
ggplot(data = ToothGrowth, aes(x = len, color = supp)) +
  geom_line(stat = "density") +
  geom_rug()
Courbes de densité avec le package ggplot2

Clairement, on gagne en nombre d’instructions à taper dans la console et en clarté d’expression également, grâce notamment à l’usage de formules permettant de décrire la relation entre chacune des variables utilisées pour construire la représentation graphique.

Les formules R

Les formules utilisées dans le système lattice sont presque identiques à celles retouvées dans les modèles d’analyse de variance (aov) ou de régression (lm). En réalité, la notation par formule qu’utilise R est celle proposée par Wilkinson et coll. dans les années 70 pour schématiser la relation entre plusieurs variables dans un plan d’expérience. Plus spécifiquement, l’idée revient à exprimer une relation fonctionnelle, symbolise´e par l’opérateur ~, entre une variable re´ponse y et une ou plusieurs variables explicatives. Disons, pour simplifier, que y est une variable numérique, de même que x, et que a et b sont des variables catégorielles (des facteurs dans le langage R). Voici les principales relations auxquelles on peut s’intéresser dans un modèle statistique linéaire :

  • y ~ x : régression linéaire simple,
  • y ~ x + 0 : idem avec suppression du terme d’ordonnée à l’origine,
  • y ~ a + b : ANOVA avec deux effets principaux,
  • y ~ a * b : idem avec interaction (équivalent à 1 + a + b + a:b),
  • y ~ a / b : idem en considérant une relation d’emboîtement (équivalent à 1 + a + b + a %in% b).

Un exemple typique d’utilisation pour un modèle d’ANOVA à trois facteurs est donné ci-dessous :

fm <- y ~ a * b * c # modèle de base (A, B, C, AB, AC, BC, ABC)
mod1 <- aov(fm, data = dfrm) # estimation des parame`tres du mode`le
update(mod1, . ~ . - a:b:c) # suppression de l'interaction ABC

Quant on y réfléchit un peu, les relations ci-dessus peuvent très bien s’appliquer au cas de la composition graphique : y ~ x signifie dans ce cas que l’on souhaite représenter l’évolution de y en fonction de x. En d’autres termes, on s’intéresse à un nuage de dispersion. Le package lattice ajoute les notations suivantes :

  • ~ x : dans le cas où l’on ne décrit qu’une seule variable (i.e., sa distribution),
  • a | b : dans le cas où l’on considère la variable a, conditionnellement à la variable b, c’est-à-dire les niveaux de a pour chacun des niveaux de b (ce qui revient à l’interaction a:b citée ci-dessus).

Cette dernière notation se révèlera être très utile dans le cas des représentations graphiques conditionnelles, par exemple lorsque l’on souhaite afficher la distribution d’une variable numérique dans différents groupes d’individus définis par les niveaux d’une variable catégorielle, ou lorsque l’on souhaite surligner d’une couleur différentes les points d’un diagramme de dispersion selon la valeur prise par une troisième variable.

Les formules R sont omniprésentes dans les modèles statistiques, dans les graphiques, mais également dans certaines commandes d’agrégation. Au bout du compte, avec une même formule il est possible de calculer des moyennes de groupes, réaliser une ANOVA et construire la représentation graphique associée. En voici un exemple :

fm <- len ~ supp
m <- aggregate(fm, data = ToothGrowth, mean)
summary(aov(fm, data = ToothGrowth))
bwplot(fm, data = ToothGrowth)

Principaux types de graphiques avec lattice (et ggplot2)

Même si le package lattice fournit moins de commandes que ggplot2, il n’en demeure pas moins qu’il est tout aussi facile de réaliser des représentations graphiques simples en un tour de main. Voici quelques exemples de représentations graphiques uni- et bivariées. Les données d’illustration sont les mêmes que celles utilisées plus haut (ToothGrowth): il s’agit d’une expérience de biologie dans laquelle on s’intéresse à la croissance des odontoblastes de cochons d’inde quantifiée par leur longueur (variable len) lorsqu’on administre à ces derniers de la vitamine C soit sous forme d’acide ascorbique soit sous forme de jus d’orange (supp, OJ = jus d’orange), à différentes doses (dose, en mg).

Histogramme

Un histogramme d’effectifs se construit avec histogram. Puisqu’il s’agit de décrire une seule variable, ou sa distribution plus précisément, la formule à employer ne contient pas de variable à gauche du symbole ~ et l’on se contente d’écrire la variable à résumer à droite dans la formule :

histogram(~len, data = ToothGrowth, type = "count")
Histogramme d’effectifs

L’option type = "count" permet de forcer la représentation sous forme d’effectifs puisque, par défaut, c’est la densité qui est représentée. La formulation équivalente sous ggplot2 serait :

ggplot(data = ToothGrowth, aes(x = len)) +
  geom_histogram(binwidth = 5)

(Ou alors qplot(x = len, data = ToothGrowth, geom = "histogram", binwidth = 5).)

En ajoutant une facette pour tenir compte de la variable supp, cela donne :

histogram(~ len | supp, data = ToothGrowth, breaks = seq(0, 40, by = 5))
Histogramme d’effectifs conditionné sur une variable catégorielle

Avec ggplot2, les facettes sont gérées grâce aux commandes facet_grid et facet_wrap.

Courbe de densité

Une courbe de densité se construit à l’aide de densityplot et la syntaxe est strictement identique à celle de histogram, à l’option type= près.

densityplot(~len, data = ToothGrowth, plot.points = FALSE, from = 0, to = 40)
Courbe de densité

Il est possible de régler le paramètre de lissage à l’aide de l’option bw= : des valeurs plus élevées résultent en une courbe beaucoup plus lissée (essayez avec bw = 10 !) et donc beaucoup moins sensible aux variations locales de la densité.

À ce stade, on peut en profiter pour discuter les options de conditionnement sur une variable catégorielle et la manière de gérer la présentation graphique : dans le cas d’un histogramme, il est délicat de superposer deux distributions ou plus sur le même graphique, même en ajoutant de la transparence, d’où l’idée de représenter les distributions dans des panneaux graphiques séparés. C’est ce qu’on a réalisé en indiquant que l’on souhaitait décrire la variable len conditionnellement aux valeurs prises par supp (~ len | supp). Dans ce cas, l’opérateur | invoque une facette et un decoupage en autant de panneaux graphiques qu’il y a de valeurs uniques dans la variable supp. Une autre approche consiste à utiliser l’option groups=, et dans ce cas les différentes distributions seront affichées dans le même panneau graphique. Dans le cas d’une courbe de densité, cela revient à les superposer sur la même fenêtre graphique, avec un système de coordonnées unique. Les deux options de conditionnement peuvent être combinées naturellement.

Voici un exemple de graphique conditionnel un peu plus élaboré :

densityplot(~len,
  data = ToothGrowth, groups = supp, auto.key = TRUE, xlab = "len",
  par.settings = list(superpose.line = list(col = c("coral", "cornflowerblue")))
)
Courbe de densité conditionnelle

Au passage, on en a profité pour modifier le thème de couleur. Notez qu’en utilisant par.settings=, lattice se charge de coordonner les couleurs de la légende (auto.key = TRUE) avec celle des éléments graphiques correspondants.

L’équivalent sous ggplot2 revient à peu près à l’instruction suivante :

ggplot(data = ToothGrowth) +
  aes(x = len, colour = supp) +
  geom_line(stat = "density") +
  expand_limits(x = c(0, 40)) +
  scale_colour_manual("", values = c("coral", "cornflowerblue")) +
  theme_bw()

Diagramme en barres

Les diagrammes en barres peuvent avantageusement être remplacés par des diagrammes en points, tels que les diagrammes de Cleveland (cf. plus loin), mais en attendant voici comment en réaliser un à l’aide de barchart à partir de données agrégées :

library(latticeExtra, quietly = TRUE)
m <- aggregate(len ~ supp + dose, data = ToothGrowth, mean)
barchart(len ~ dose, data = m, groups = supp, horizontal = FALSE, auto.key = TRUE, par.settings = ggplot2like())
Diagramme en barres

Notons que par.settings= permet non seulement de fournir des options additionnelles pour contrôler le rendu des éléments graphiques (couleur, type de ligne ou de symboles, etc.) mais également d’utiliser des thèmes graphiques disponibles dans le package latticeExtra.

Diagramme de type boîtes à moustaches

Les diagrammes en forme de boîtes à moustaches sont obtenus à l’aide de la commande bwplot. Voici un exemple d’utilisation :

bwplot(len ~ supp, data = ToothGrowth, pch = "|")
Diagramme en forme de boîtes à moustaches

L’option pch= permet de contrôler la manière dont la médiane est figurée dans la boîte. Par défaut il s’agit d’un simple point, mais si l’on souhaite utiliser les représentations plus classiques, telles que celles trouvées dans boxplot ou geom_boxplot, il suffit de suivre l’exemple ci-dessus. Notons que dans le cas de cette représentation graphique, le conditionnement sur la variable supp est d’emblée réalisé par l’utilisation d’une formule invoquant la variable de conditionnement à droite de l’opérateur ~.

Diagramme en points

Le même type de représentation graphique peut être obtenu en utilisant directement les données individuelles, et non leur résumé en cinq points (tel que fournit par summary et exploité par bwplot). Dans ce cas, il s’agit de la commande dotplot, qui permet de construire des diagrammes de Cleveland (moyenne ou effectif total calculé pour une variable en fonction des niveaux d’une autre variable) ou, dans le cas où la variable à résumer consiste en une série de mesures individuelles numériques, des diagrammes de dispersion. Voici une illustration pour ce dernier cas de figure :

dotplot(len ~ supp, ToothGrowth, jitter.x = TRUE)
Diagramme en points

Diagramme de dispersion

Enfin, un diagramme de dispersion est construit à l’aide de la commande xyplot.

xyplot(len ~ dose, ToothGrowth, type = c("p", "smooth"))
Diagramme de dispersion

Même si l’exemple ne s’y prête guère, on en a profité pour ajouter une courbe lowess de régression afin d’indiquer la tendance de covariation entre les deux variables numériques. L’aide en ligne pour xyplot n’est pas très utile dans ce cas, et il faut en fait aller regarder les options de personnalisation disponibles dans la sous-fonction correspondante : panel.xyplot.

Cartes

Pour une présentation de l’analyse spatiale sous R, se référer au chapitre dédié.

Il existe de multiple approches pour réaliser des cartes sous R, y compris avec ggplot2, mais également de manière native avec les extensions sp et sf. Il existe également des extensions apportant des fonctionalités additionnelles comme ggmap, mapview ou encore tmap.

Pour une introduction succincte en français, on pourra se référer à la section 5.4 du spport de cours Logiciel R et programmation d’Ewan Gallic.

Voir également l’excellente présentation Données géospatiales et cartographie avec R de Nicolas Roelandt : https://roelandtn.frama.io/slides/2090628_meetup_Raddict_datageo.html.

En complément (en anglais), la vignette Plotting Simple Features de l’extension sf ou encore le chapitre Making maps with R de l’ouvrage Geocomputation with R de Robin Lovelace, Jakub Nowosad et Jannes Muenchow.

Autres extensions graphiques

Pour trouver l’inspiration et des exemples de code, rien ne vaut l’excellent site https://www.r-graph-gallery.com/.

GGally

L’extension GGally, déjà abordée dans d’autres chapitres, fournit plusieurs fonctions graphiques d’exploration des résultats d’un modèle ou des relations entre variables.

reg <- lm(Sepal.Length ~ Sepal.Width + Petal.Length + Petal.Width, data = iris)
library(GGally)
ggcoef(reg)

data(tips, package = "reshape")
ggpairs(tips)

Plus d’information : https://ggobi.github.io/ggally/

ggpubr

L’extension ggpubr fournit plusieurs fonctions pour produire clés en main différents graphiques bivariés avec une mise en forme allégée.

library(ggpubr)
data("ToothGrowth")
df <- ToothGrowth
ggboxplot(df,
  x = "dose", y = "len",
  color = "dose", palette = c("#00AFBB", "#E7B800", "#FC4E07"),
  add = "jitter", shape = "dose"
)

data("mtcars")
dfm <- mtcars
# Convert the cyl variable to a factor
dfm$cyl <- as.factor(dfm$cyl)
# Add the name colums
dfm$name <- rownames(dfm)
# Calculate the z-score of the mpg data
dfm$mpg_z <- (dfm$mpg - mean(dfm$mpg)) / sd(dfm$mpg)
dfm$mpg_grp <- factor(ifelse(dfm$mpg_z < 0, "low", "high"),
  levels = c("low", "high")
)

ggbarplot(dfm,
  x = "name", y = "mpg_z",
  fill = "mpg_grp", # change fill color by mpg_level
  color = "white", # Set bar border colors to white
  palette = "jco", # jco journal color palett. see ?ggpar
  sort.val = "asc", # Sort the value in ascending order
  sort.by.groups = FALSE, # Don't sort inside each group
  x.text.angle = 90, # Rotate vertically x axis texts
  ylab = "MPG z-score",
  xlab = FALSE,
  legend.title = "MPG Group"
)

ggdotchart(dfm,
  x = "name", y = "mpg_z",
  color = "cyl", # Color by groups
  palette = c("#00AFBB", "#E7B800", "#FC4E07"), # Custom color palette
  sorting = "descending", # Sort value in descending order
  add = "segments", # Add segments from y = 0 to dots
  add.params = list(color = "lightgray", size = 2), # Change segment color and size
  group = "cyl", # Order by groups
  dot.size = 6, # Large dot size
  label = round(dfm$mpg_z, 1), # Add mpg values as dot labels
  font.label = list(
    color = "white", size = 9,
    vjust = 0.5
  ), # Adjust label parameters
  ggtheme = theme_pubr() # ggplot2 theme
) +
  geom_hline(yintercept = 0, linetype = 2, color = "lightgray")

Plus d’informations : https://rpkgs.datanovia.com/ggpubr/

ggdendro

L’extension ggendro avec sa fonction ggdendrogram permet de représenter facilement des dendrogrammes avec ggplot2.

library(ggplot2)
library(ggdendro)
hc <- hclust(dist(USArrests), "ave")
hcdata <- dendro_data(hc, type = "rectangle")
ggplot() +
  geom_segment(data = segment(hcdata), aes(x = x, y = y, xend = xend, yend = yend)) +
  geom_text(data = label(hcdata), aes(x = x, y = y, label = label, hjust = 0), size = 3) +
  coord_flip() +
  scale_y_reverse(expand = c(0.2, 0))

### demonstrate plotting directly from object class hclust
ggdendrogram(hc)

ggdendrogram(hc, rotate = TRUE)

Plus d’informations : https://cran.r-project.org/web/packages/ggdendro/vignettes/ggdendro.html

circlize

L’extension circlize est l’extension de référence quand il s’agit de représentations circulaires. Un ouvrage entier lui est dédié : https://jokergoo.github.io/circlize_book/book/.

Voici un exemple issu de https://www.data-to-viz.com/story/AdjacencyMatrix.html.

library(tidyverse)

# Load data
data <- read.table("https://raw.githubusercontent.com/holtzy/data_to_viz/master/Example_dataset/13_AdjacencyDirectedWeighted.csv", header = TRUE)
# short names
colnames(data) <- c("Africa", "East Asia", "Europe", "Latin Ame.", "North Ame.", "Oceania", "South Asia", "South East Asia", "Soviet Union", "West.Asia")
rownames(data) <- colnames(data)

# I need a long format
data_long <- data %>%
  rownames_to_column() %>%
  gather(key = "key", value = "value", -rowname)


library(circlize)
# parameters
circos.clear()
circos.par(start.degree = 90, gap.degree = 4, track.margin = c(-0.1, 0.1), points.overflow.warning = FALSE)
par(mar = rep(0, 4))

# color palette
library(viridis)
mycolor <- viridis(10, alpha = 1, begin = 0, end = 1, option = "D")
mycolor <- mycolor[sample(1:10)]

# Base plot
chordDiagram(
  x = data_long,
  grid.col = mycolor,
  transparency = 0.25,
  directional = 1,
  direction.type = c("arrows", "diffHeight"),
  diffHeight = -0.04,
  annotationTrack = "grid",
  annotationTrackHeight = c(0.05, 0.1),
  link.arr.type = "big.arrow",
  link.sort = TRUE,
  link.largest.ontop = TRUE
)

# Add text and axis
circos.trackPlotRegion(
  track.index = 1,
  bg.border = NA,
  panel.fun = function(x, y) {
    xlim <- get.cell.meta.data("xlim")
    sector.index <- get.cell.meta.data("sector.index")

    # Add names to the sector.
    circos.text(
      x = mean(xlim),
      y = 3.2,
      labels = sector.index,
      facing = "bending",
      cex = 0.8
    )

    # Add graduation on axis
    circos.axis(
      h = "top",
      major.at = seq(from = 0, to = xlim[2], by = ifelse(test = xlim[2] > 10, yes = 2, no = 1)),
      minor.ticks = 1,
      major.tick.percentage = 0.5,
      labels.niceFacing = FALSE
    )
  }
)
`major.tick.percentage` is not used any more, please directly use argument `major.tick.length`.
`major.tick.percentage` is not used any more, please directly use argument `major.tick.length`.
`major.tick.percentage` is not used any more, please directly use argument `major.tick.length`.
`major.tick.percentage` is not used any more, please directly use argument `major.tick.length`.
`major.tick.percentage` is not used any more, please directly use argument `major.tick.length`.
`major.tick.percentage` is not used any more, please directly use argument `major.tick.length`.
`major.tick.percentage` is not used any more, please directly use argument `major.tick.length`.
`major.tick.percentage` is not used any more, please directly use argument `major.tick.length`.
`major.tick.percentage` is not used any more, please directly use argument `major.tick.length`.
`major.tick.percentage` is not used any more, please directly use argument `major.tick.length`.

Diagrammes de Sankey

Les diagrammes de Sankey sont un type alternatif de représentation de flux. Voici un premier exemple, qui reprend les données utilisées pour le diagramme circulaire précédent, avec la fonction sankeyNetwork de l’extension sankeyNetwork.

# Package
library(networkD3)

# I need a long format
data_long <- data %>%
  rownames_to_column() %>%
  gather(key = "key", value = "value", -rowname) %>%
  filter(value > 0)
colnames(data_long) <- c("source", "target", "value")
data_long$target <- paste(data_long$target, " ", sep = "")

# From these flows we need to create a node data frame: it lists every entities involved in the flow
nodes <- data.frame(name = c(as.character(data_long$source), as.character(data_long$target)) %>% unique())

# With networkD3, connection must be provided using id, not using real name like in the links dataframe.. So we need to reformat it.
data_long$IDsource <- match(data_long$source, nodes$name) - 1
data_long$IDtarget <- match(data_long$target, nodes$name) - 1

# prepare colour scale
ColourScal <- 'd3.scaleOrdinal() .range(["#FDE725FF","#B4DE2CFF","#6DCD59FF","#35B779FF","#1F9E89FF","#26828EFF","#31688EFF","#3E4A89FF","#482878FF","#440154FF"])'

# Make the Network
sankeyNetwork(
  Links = data_long, Nodes = nodes,
  Source = "IDsource", Target = "IDtarget",
  Value = "value", NodeID = "name",
  sinksRight = FALSE, colourScale = ColourScal, nodeWidth = 40, fontSize = 13, nodePadding = 20
)

Une alternative possible est fournie par l’extension ggalluvial et ses géométries geom_alluvium et geom_stratum.

library(ggalluvial)
ggplot(data = as.data.frame(Titanic)) +
  aes(axis1 = Class, axis2 = Sex, axis3 = Age, y = Freq) +
  scale_x_discrete(limits = c("Class", "Sex", "Age"), expand = c(.1, .05)) +
  xlab("Demographic") +
  geom_alluvium(aes(fill = Survived)) +
  geom_stratum() +
  geom_text(stat = "stratum", infer.label = TRUE) +
  theme_minimal()
Warning: The parameter `infer.label` is deprecated.
Use `aes(label = after_stat(stratum))`.

Mentionnons également l’extension riverplot pour la création de diagrammes de Sankey.

DiagrammeR

DiagrammeR est dédiée à la réalisation de diagrammes en ayant recours à la syntaxe Graphviz (via la fonction grViz) ou encore à la syntaxe Mermaid (via la fonction mermaid).

library(DiagrammeR)
grViz("
digraph boxes_and_circles {

  # a 'graph' statement
  graph [overlap = true, fontsize = 10]

  # several 'node' statements
  node [shape = box,
        fontname = Helvetica]
  A; B; C; D; E; F

  node [shape = circle,
        fixedsize = true,
        width = 0.9] // sets as circles
  1; 2; 3; 4; 5; 6; 7; 8

  # several 'edge' statements
  A->1 B->2 B->3 B->4 C->A
  1->D E->A 2->4 1->5 1->F
  E->6 4->6 5->7 6->7 3->8
}
")
mermaid("
graph LR
A(Rounded)-->B[Rectangular]
B-->C{A Rhombus}
C-->D[Rectangle One]
C-->E[Rectangle Two]
")
mermaid("
sequenceDiagram
  customer->>ticket seller: ask ticket
  ticket seller->>database: seats
  alt tickets available
    database->>ticket seller: ok
    ticket seller->>customer: confirm
    customer->>ticket seller: ok
    ticket seller->>database: book a seat
    ticket seller->>printer: print ticket
  else sold out
    database->>ticket seller: none left
    ticket seller->>customer: sorry
  end
")
mermaid("
gantt
       dateFormat  YYYY-MM-DD
       title Adding GANTT diagram functionality to mermaid

       section A section
       Completed task            :done,    des1, 2014-01-06,2014-01-08
       Active task               :active,  des2, 2014-01-09, 3d
       Future task               :         des3, after des2, 5d
       Future task2              :         des4, after des3, 5d

       section Critical tasks
       Completed task in the critical line :crit, done, 2014-01-06,24h
       Implement parser and jison          :crit, done, after des1, 2d
       Create tests for parser             :crit, active, 3d
       Future task in critical line        :crit, 5d
       Create tests for renderer           :2d
       Add to mermaid                      :1d

       section Documentation
       Describe gantt syntax               :active, a1, after des1, 3d
       Add gantt diagram to demo page      :after a1  , 20h
       Add another diagram to demo page    :doc1, after a1  , 48h

       section Last section
       Describe gantt syntax               :after doc1, 3d
       Add gantt diagram to demo page      :20h
       Add another diagram to demo page    :48h
")

Plus d’informations : https://rich-iannone.github.io/DiagrammeR/

highcharter

L’extension highcharter permet de réaliser des graphiques HTML utilisant la librairie Javascript Highcharts.js.

library("highcharter")
data(diamonds, mpg, package = "ggplot2")

hchart(mpg, "scatter", hcaes(x = displ, y = hwy, group = class))
library(tidyverse)
library(highcharter)
mpgman3 <- mpg %>%
  group_by(manufacturer) %>%
  summarise(n = n(), unique = length(unique(model))) %>%
  arrange(-n, -unique)

hchart(mpgman3, "treemap", hcaes(x = manufacturer, value = n, color = unique))
data(unemployment)

hcmap("countries/us/us-all-all",
  data = unemployment,
  name = "Unemployment", value = "value", joinBy = c("hc-key", "code"),
  borderColor = "transparent"
) %>%
  hc_colorAxis(dataClasses = color_classes(c(seq(0, 10, by = 2), 50))) %>%
  hc_legend(
    layout = "vertical", align = "right",
    floating = TRUE, valueDecimals = 0, valueSuffix = "%"
  )

Plus d’informations : http://jkunst.com/highcharter/

Conditions et comparaisons

Une condition est une expression logique dont le résultat est soit TRUE (vrai) soit FALSE (faux).

Une condition comprend la plupart du temps un opérateur de comparaison. Les plus courants sont les suivants :

Opérateur de comparaison Signification
== égal à
!= différent de
> strictement supérieur à
< strictement inférieur à
>= supérieur ou égal à
<= inférieur ou égal à

Voyons tout de suite un exemple :

library(questionr)
data(hdv2003)
d <- hdv2003
str(d$sexe == "Homme")
 logi [1:2000] FALSE FALSE TRUE TRUE FALSE FALSE ...

Que s’est-il passé ? Nous avons fourni à R une condition qui signifie « la valeur de la variable sexe vaut “Homme” ». Et il nous a renvoyé un vecteur avec autant d’éléments qu’il y’a d’observations dans d, et dont la valeur est TRUE si l’observation correspond à un homme et FALSE dans les autres cas.

Prenons un autre exemple. On n’affichera cette fois que les premiers éléments de notre variable d’intérêt à l’aide de la fonction head :

head(d$age)
[1] 28 23 59 34 71 35
head(d$age > 40)
[1] FALSE FALSE  TRUE FALSE  TRUE FALSE

On voit bien ici qu’à chaque élément du vecteur d$age dont la valeur est supérieure à 40 correspond un élément TRUE dans le résultat de la condition.

On peut combiner ou modifier des conditions à l’aide des opérateurs logiques habituels :

Opérateur logique Signification
& et logique
| ou logique
! négation logique

Comment les utilise-t-on ? Voyons tout de suite des exemples. Supposons que je veuille déterminer quels sont dans mon échantillon les hommes ouvriers spécialisés :

d$sexe == "Homme" & d$qualif == "Ouvrier specialise"

Si je souhaite identifier les personnes qui bricolent ou qui font la cuisine :

d$bricol == "Oui" | d$cuisine == "Oui"

Si je souhaite isoler les femmes qui ont entre 20 et 34 ans :

d$sexe == "Femme" & d$age >= 20 & d$age <= 34

Si je souhaite récupérer les enquêtés qui ne sont pas cadres, on peut utiliser l’une des deux formes suivantes :

d$qualif != "Cadre"
!(d$qualif == "Cadre")

Lorsqu’on mélange « et » et « ou » il est nécessaire d’utiliser des parenthèses pour différencier les blocs. La condition suivante identifie les femmes qui sont soit cadre, soit employée :

d$sexe == "Femme" & (d$qualif == "Employe" | d$qualif == "Cadre")

L’opérateur %in% peut être très utile : il teste si une valeur fait partie des éléments d’un vecteur. Ainsi on pourrait remplacer la condition précédente par :

d$sexe == "Femme" & d$qualif %in% c("Employe", "Cadre")

Enfin, signalons qu’on peut utiliser les fonctions table ou summary pour avoir une idée du résultat de notre condition :

table(d$sexe)

Homme Femme 
  899  1101 
table(d$sexe == "Homme")

FALSE  TRUE 
 1101   899 
summary(d$sexe == "Homme")
   Mode   FALSE    TRUE 
logical    1101     899 

Formules

Ce chapitre vise à illustrer l’utilisation de la notation formule de R, qui désigne l’emploi de cette notation par l’expression formula. Cette notation est utilisée par de très nombreuses fonctions de R : on en a notamment vu plusieurs exemples dans le chapitre sur les graphiques bivariés, car l’extension ggplot2 se sert de cette notation dans ses paramètres facet_wrap et facet_grid.

Dans ce chapitre, on verra comment se servir de la notation formule dans deux contextes différents. D’une part, on verra que deux fonctions basiques de R se servent de cette notation pour produire des tableaux croisés et des statistiques bivariées. D’autre part, on verra que l’extension lattice se sert de cette notation pour créer des graphiques panelisés, dits graphiques à petits multiples.

Dans plusieurs autres chapitres, les opérations décrites ci-dessus sont effectuées avec les extensions dplyr d’une part, et ggplot2 d’autre part. On se servira également de ces extensions dans ce chapitre, de manière à mener une comparaison des différentes manières d’effectuer certaines opérations dans R, avec ou sans la notation formule :

library(dplyr)
library(ggplot2)

Statistiques descriptives

Les premiers exemples de ce chapitre montrent l’utilisation de cette notation pour produire des tableaux croisés et des statistiques descriptives. Le jeu de données utilisé, hdv2003, a déjà été utilisé dans plusieurs chapitres, et font partie de l’extension questionr. Chargeons cette extension et le jeu de données hdv2003 :

library(questionr)
data(hdv2003)

Pour rappel, ce jeu de données contient des individus, leur âge, leur statut professionnel, et le nombre d’heures quotidiennes passées à regarder la télévision.

glimpse(hdv2003, 75)
Rows: 2,000
Columns: 20
$ id            <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 1...
$ age           <int> 28, 23, 59, 34, 71, 35, 60, 47, 20, 28, 65, 47, ...
$ sexe          <fct> Femme, Femme, Homme, Homme, Femme, Femme, Femme,...
$ nivetud       <fct> "Enseignement superieur y compris technique supe...
$ poids         <dbl> 2634.3982, 9738.3958, 3994.1025, 5731.6615, 4329...
$ occup         <fct> "Exerce une profession", "Etudiant, eleve", "Exe...
$ qualif        <fct> Employe, NA, Technicien, Technicien, Employe, Em...
$ freres.soeurs <int> 8, 2, 2, 1, 0, 5, 1, 5, 4, 2, 3, 4, 1, 5, 2, 3, ...
$ clso          <fct> Oui, Oui, Non, Non, Oui, Non, Oui, Non, Oui, Non...
$ relig         <fct> Ni croyance ni appartenance, Ni croyance ni appa...
$ trav.imp      <fct> Peu important, NA, Aussi important que le reste,...
$ trav.satisf   <fct> Insatisfaction, NA, Equilibre, Satisfaction, NA,...
$ hard.rock     <fct> Non, Non, Non, Non, Non, Non, Non, Non, Non, Non...
$ lecture.bd    <fct> Non, Non, Non, Non, Non, Non, Non, Non, Non, Non...
$ peche.chasse  <fct> Non, Non, Non, Non, Non, Non, Oui, Oui, Non, Non...
$ cuisine       <fct> Oui, Non, Non, Oui, Non, Non, Oui, Oui, Non, Non...
$ bricol        <fct> Non, Non, Non, Oui, Non, Non, Non, Oui, Non, Non...
$ cinema        <fct> Non, Oui, Non, Oui, Non, Oui, Non, Non, Oui, Oui...
$ sport         <fct> Non, Oui, Oui, Oui, Non, Oui, Non, Non, Non, Oui...
$ heures.tv     <dbl> 0.0, 1.0, 0.0, 2.0, 3.0, 2.0, 2.9, 1.0, 2.0, 2.0...

Tableaux croisés avec xtabs

Utilisons, pour ce premier exemple, la variable occup du jeu de données hdv2003, qui correspond au statut professionnel des individus inclus dans l’échantillon. La fonction de base pour compter les individus par statut est la fonction table :

table(hdv2003$occup)

Exerce une profession               Chomeur 
                 1049                   134 
      Etudiant, eleve              Retraite 
                   94                   392 
  Retire des affaires              Au foyer 
                   77                   171 
        Autre inactif 
                   83 

Avec la fonction xtabs, le même résultat est produit à partir de la notation suivante :

xtabs(~occup, data = hdv2003)
occup
Exerce une profession               Chomeur 
                 1049                   134 
      Etudiant, eleve              Retraite 
                   94                   392 
  Retire des affaires              Au foyer 
                   77                   171 
        Autre inactif 
                   83 

Le premier argument est une formule, au sens où R entend cette expression. Le second argument, data, correspond au jeu de données auquel la formule doit être appliquée. On pourra se passer d’écrire explicitement cet argument dans les exemples suivants.

L’avantage de la fonction xtabs n’est pas évident dans ce premier exemple. En réalité, cette fonction devient utile lorsque l’on souhaite construire un ou plusieurs tableau(x) croisé(s). Par exemple, pour croiser la variable occup avec la variable sexe, une solution constiste à écrire :

with(hdv2003, table(occup, sexe))
                       sexe
occup                   Homme Femme
  Exerce une profession   520   529
  Chomeur                  54    80
  Etudiant, eleve          48    46
  Retraite                208   184
  Retire des affaires      39    38
  Au foyer                  0   171
  Autre inactif            30    53

Ou alors, ce qui revient au même :

table(hdv2003$occup, hdv2003$sexe)

Avec xtabs, la même opération s’écrit de la manière suivante :

xtabs(~ occup + sexe, hdv2003)
                       sexe
occup                   Homme Femme
  Exerce une profession   520   529
  Chomeur                  54    80
  Etudiant, eleve          48    46
  Retraite                208   184
  Retire des affaires      39    38
  Au foyer                  0   171
  Autre inactif            30    53

Cette écriture est plus courte que le code équivalent dans dplyr :

hdv2003 %>%
  group_by(occup) %>%
  summarise(
    Homme = sum(sexe == "Homme"),
    Femme = sum(sexe == "Femme")
  )
`summarise()` ungrouping output (override with `.groups` argument)

Par contre, on pourra éventuellement utiliser count de dplyr. ATTENTION : le format du résultat ne sera pas le même.

hdv2003 %>%
  group_by(occup) %>%
  count(sexe)

Pour un tableau croisé joliment mis en forme, on pourra avoir recours à tbl_cross de gtsummary.

library(gtsummary)
hdv2003 %>%
  tbl_cross(row = "occup", col = "sexe", percent = "row")
Characteristic sexe Total
Homme Femme
occup
Exerce une profession 520 (50%) 529 (50%) 1,049 (100%)
Chomeur 54 (40%) 80 (60%) 134 (100%)
Etudiant, eleve 48 (51%) 46 (49%) 94 (100%)
Retraite 208 (53%) 184 (47%) 392 (100%)
Retire des affaires 39 (51%) 38 (49%) 77 (100%)
Au foyer 0 (0%) 171 (100%) 171 (100%)
Autre inactif 30 (36%) 53 (64%) 83 (100%)
Total 899 (45%) 1,101 (55%) 2,000 (100%)

De plus, xtabs permet de créer plusieurs tableaux croisés en une seule formule :

xtabs(~ occup + sexe + trav.imp, hdv2003)
, , trav.imp = Le plus important

                       sexe
occup                   Homme Femme
  Exerce une profession    13    16
  Chomeur                   0     0
  Etudiant, eleve           0     0
  Retraite                  0     0
  Retire des affaires       0     0
  Au foyer                  0     0
  Autre inactif             0     0

, , trav.imp = Aussi important que le reste

                       sexe
occup                   Homme Femme
  Exerce une profession   159   100
  Chomeur                   0     0
  Etudiant, eleve           0     0
  Retraite                  0     0
  Retire des affaires       0     0
  Au foyer                  0     0
  Autre inactif             0     0

, , trav.imp = Moins important que le reste

                       sexe
occup                   Homme Femme
  Exerce une profession   328   380
  Chomeur                   0     0
  Etudiant, eleve           0     0
  Retraite                  0     0
  Retire des affaires       0     0
  Au foyer                  0     0
  Autre inactif             0     0

, , trav.imp = Peu important

                       sexe
occup                   Homme Femme
  Exerce une profession    20    32
  Chomeur                   0     0
  Etudiant, eleve           0     0
  Retraite                  0     0
  Retire des affaires       0     0
  Au foyer                  0     0
  Autre inactif             0     0

Cet exemple permet simplement de réaliser que la variable trav.imp, qui contient les réponses à une question portant sur l’importance du travail, n’a été mesurée (c’est-à-dire que la question n’a été posée) qu’aux seuls individus actifs de l’échantillon.

Statistiques bivariées avec aggregate

aggregate(heures.tv ~ sexe, mean, data = hdv2003)

Ici, le premier argument est à nouveau une formule. Le second argument correspond à la statistique descriptive que l’on souhaite obtenir, et le dernier argument indique le jeu de données auquel appliquer les deux autres arguments. On peut d’ailleurs obtenir le même résultat en respectant de manière plus stricte l’ordre des arguments dans la syntaxe de la fonction aggregate :

aggregate(heures.tv ~ sexe, hdv2003, mean)

Cette écriture est, à nouveau, plus compacte que le code équivalent dans dplyr, qui demande de spécifier le retrait des valeurs manquantes :

hdv2003 %>
  group_by(sexe) %>%
  summarise(heures.tv = mean(heures.tv, na.rm = TRUE))

À nouveau, on va pouvoir combiner plusieurs variables dans la formule que l’on passe à aggregate, ce qui va permettre d’obtenir la moyenne des heures de télévision quotidiennes par sexe et par statut professionnel :

aggregate(heures.tv ~ sexe + occup, hdv2003, mean)

La même opération dplyr :

hdv2003 %>%
  group_by(occup, sexe) %>%
  summarise(heures.tv = mean(heures.tv, na.rm = TRUE))

La fonction aggregate permet bien sûr d’utiliser une autre fonction que la moyenne, comme dans cet exemple, suivi de son équivalent avec dplyr :

# âge médian par sexe et statut professionnel
aggregate(age ~ sexe + occup, hdv2003, median)
# code équivalent avec l'extension 'dplyr'
hdv2003 %>%
  group_by(occup, sexe) %>%
  summarise(age = median(age, na.rm = TRUE))

Si, comme dans le cas de summarise, on souhaite passer des arguments supplémentaires à la fonction median, il suffit de les lister à la suite du nom de la fonction. Par exemple, on écrirait : aggregate(age ~ sexe + occup, hdv2003, median, na.rm = TRUE). Ceci étant, aggregate utilise par défaut l’option na.action = na.omit, donc il est bon de se rappeler que l’on peut désactiver cette option en utilisant l’option na.action = na.pass, ce qui permet éventuellement de conserver des lignes vides dans le tableau de résultat.

La fonction aggregate permet, par ailleurs, d’obtenir des résultats à plusieurs colonnes. Dans l’exemple ci-dessus, on illustre ce principe avec la fonction range, qui renvoie deux résultats (la valeur minimale et la valeur maximale de la variable, qui est toujours la variable age), chacun présentés dans une colonne :

aggregate(age ~ sexe + occup, hdv2003, range)
    sexe                 occup age.1 age.2
1  Homme Exerce une profession    18    63
2  Femme Exerce une profession    18    67
3  Homme               Chomeur    18    63
4  Femme               Chomeur    18    63
5  Homme       Etudiant, eleve    18    34
6  Femme       Etudiant, eleve    18    35
7  Homme              Retraite    48    92
8  Femme              Retraite    41    96
9  Homme   Retire des affaires    57    91
10 Femme   Retire des affaires    57    93
11 Femme              Au foyer    22    90
12 Homme         Autre inactif    39    71
13 Femme         Autre inactif    19    97

Cette fonction ne peut pas être facilement écrite dans dplyr sans réécrire chacune des colonnes, ce que le bloc de code suivant illustre. On y gagne en lisibilité dans les intitulés de colonnes :

hdv2003 %>%
  group_by(occup, sexe) %>%
  summarise(
    min = min(age, na.rm = TRUE),
    max = max(age, na.rm = TRUE)
  )

Depuis la version 1.0.0 de dplyr, summarise accepte maintenant des fonctions pouvant renvoyer plusieurs valeurs, créant ainsi autant de lignes (voir https://www.tidyverse.org/blog/2020/03/dplyr-1-0-0-summarise/).

hdv2003 %>%
  group_by(occup, sexe) %>%
  summarise(age = range(age, na.rm = TRUE), type = c("min", "max"))
`summarise()` regrouping output by 'occup', 'sexe' (override with `.groups` argument)

On pourrait de même définir sa propre fonction et la passer à aggregate :

f <- function(x) c(mean = mean(x, na.rm = TRUE), sd = sd(x, na.rm = TRUE))
aggregate(age ~ sexe + occup, hdv2003, f)
    sexe                 occup  age.mean    age.sd
1  Homme Exerce une profession 41.461538 10.438113
2  Femme Exerce une profession 40.710775 10.203864
3  Homme               Chomeur 38.925926 13.256329
4  Femme               Chomeur 38.012500 11.648321
5  Homme       Etudiant, eleve 20.895833  2.926326
6  Femme       Etudiant, eleve 21.586957  3.249452
7  Homme              Retraite 68.418269  8.018882
8  Femme              Retraite 69.510870  8.228957
9  Homme   Retire des affaires 71.179487  7.687556
10 Femme   Retire des affaires 73.789474  7.651737
11 Femme              Au foyer 50.730994 15.458412
12 Homme         Autre inactif 54.166667  6.597196
13 Femme         Autre inactif 59.962264 14.660206

Mais on réalisera vite une des limitations de aggregate dans ce cas-là : le tableau retourné ne contient pas 4 colonnes, mais 3 uniquement, ce que l’on peut vérifier à l’aide de dim ou str.

str(aggregate(age ~ sexe + occup, hdv2003, f))
'data.frame':   13 obs. of  3 variables:
 $ sexe : Factor w/ 2 levels "Homme","Femme": 1 2 1 2 1 2 1 2 1 2 ...
 $ occup: Factor w/ 7 levels "Exerce une profession",..: 1 1 2 2 3 3 4 4 5 5 ...
 $ age  : num [1:13, 1:2] 41.5 40.7 38.9 38 20.9 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "mean" "sd"

Pour ce type d’opération, dans lequel on souhaite récupérer plusieurs variables calculées afin de travailler sur ces données agrégées soit dans le cadre d’opérations numériques soit de constructions graphiques, dplyr ou Hmisc s’avèrent plus commodes. Voici un exemple avec summarize de l’extension Hmisc :

library(Hmisc, quietly = TRUE)
with(hdv2003, summarize(age, llist(sexe, occup), f))

Notons que Hmisc offre déjà une telle fonction (smean.sd), ce qui nous aurait épargné d’écrire notre propre fonction, f, et il en existe bien d’autres. Voici un exemple avec des intervalles de confiance estimés par bootstrap :

with(hdv2003, summarize(age, llist(sexe, occup), smean.cl.boot))

Et un exemple avec dplyr.

hdv2003 %>%
  group_by(sexe, occup) %>%
  summarise(
    tibble(
      age_mean = mean(age, na.rm = TRUE),
      age_sd = sd(age, na.rm = TRUE)
    )
  )
`summarise()` regrouping output by 'sexe' (override with `.groups` argument)

Enfin, il est également possible d’utiliser plusieurs variables numériques à gauche de l’opérateur ~. En voici une illustration :

aggregate(cbind(age, poids) ~ sexe + occup, hdv2003, mean)

Panels graphiques avec lattice

Les exemples suivants montreront ensuite comment la notation formule peut servir à produire des graphiques par panel avec l’extension lattice.

library(lattice)

L’extension lattice présente l’avantage d’être installée par défaut avec R. Il n’est donc pas nécessaire de l’installer préalablement.

Chargeons les mêmes données que le chapitre sur les graphiques bivariés.

# charger l'extension lisant le format CSV
library(readr)

# emplacement souhaité pour le jeu de données
file <- "data/debt.csv"

# télécharger le jeu de données s'il n'existe pas
if (!file.exists(file)) {
  download.file("http://www.stat.cmu.edu/~cshalizi/uADA/13/hw/11/debt.csv",
    file,
    mode = "wb"
  )
}

# charger les données dans l'objet 'debt'
debt <- read_csv(file)
Warning: Missing column names filled in: 'X1' [1]

-- Column specification ------------------------------------
cols(
  X1 = col_double(),
  Country = col_character(),
  Year = col_double(),
  growth = col_double(),
  ratio = col_double()
)

Rejetons rapidement un coup d’oeil à ces données, qui sont structurées par pays (variable Country) et par année (variable Year). On y trouve deux variables, growth (le taux de croissance du produit intérieur brut réel), et ratio (le ratio entre la dette publique et le produit intérieur brut), ainsi qu’une première colonne vide, ne contenant que des numéros lignes, dont on va se débarrasser :

# inspection des données
glimpse(debt, 75)
Rows: 1,171
Columns: 5
$ X1      <dbl> 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,...
$ Country <chr> "Australia", "Australia", "Australia", "Australia", "A...
$ Year    <dbl> 1946, 1947, 1948, 1949, 1950, 1951, 1952, 1953, 1954, ...
$ growth  <dbl> -3.5579515, 2.4594746, 6.4375341, 6.6119938, 6.9202012...
$ ratio   <dbl> 190.41908, 177.32137, 148.92981, 125.82870, 109.80940,...
# suppression de la première colonne
debt <- debt[, -1]

Visualisation bivariée

Le même graphique s’écrit de la manière suivante avec l’extension lattice :

xyplot(growth ~ Year, data = debt)

Visualisation par petits multiples

Appliquons désormais la même visualisation par petits multiples que vue dans le chapitre :

xyplot(growth ~ Year | Country, data = debt)

Enfin, rajoutons quelques options au graphique, afin de montrer comment l’extension lattice fonctionne :

xyplot(growth ~ Year | Country,
  type = c("o", "l"),
  main = "Données Reinhart et Rogoff corrigées, 1946-2009",
  ylab = "Taux de croissance du PIB",
  xlab = NULL,
  data = debt
)

Spécifier des modèles

Les formules R

En réalité, la notation par formule qu’utilise R est celle proposée par Wilkinson et al. dans les années 70 pour schématiser la relation entre plusieurs variables dans un plan d’expérience. Plus spécifiquement, l’idée revient à exprimer une relation fonctionnelle, symbolise´e par l’opérateur ~, entre une variable re´ponse y et une ou plusieurs variables explicatives. Disons, pour simplifier, que y est une variable d’intérêt (numérique ou facteur selon le type de modèle), x une variable numérique et que a et b sont des variables catégorielles (des facteurs dans le langage R). Voici les principales relations auxquelles on peut s’intéresser dans un modèle statistique :

  • y ~ x : régression simple,
  • y ~ x + 0 : idem avec suppression du terme d’ordonnée à l’origine,
  • y ~ a + b : régresse avec deux effets principaux indépendants,
  • y ~ a * b : idem avec interaction (équivalent à 1 + a + b + a:b),
  • y ~ a / b : idem en considérant une relation d’emboîtement (équivalent à 1 + a + b + a %in% b).

L’opérateur | est quant à lui utilisé par l’extension lme4 dans le cadre de modèles mixtes avec effets aléatoires.

Voir le chapitre dédié à la régression logistique pour des exemples de modèles multivariés et le chapitre dédié aux effets d’interaction pour plus de détails sur cette notion.

Pour aller plus loin

Comme vient de le voir dans ce chapitre, la notation formule apparaît çà et là dans les différentes fonctions de R est de ses extensions. Il est par conséquent utile d’en connaître les rudiments, et en particulier les opérateurs ~ (tilde) et +, ne serait-ce que pour pouvoir se servir des différentes fonctions présentées sur cette page. Le chapitre lattice et les formules fournit plus de détails sur ces aspects.

La notation formule devient cruciale dès que l’on souhaite rédiger des modèles : la formule y ~ x, par exemple, qui est équivalente à la formule y ~ 1 + x, correspond à l’équation mathématique Y = a + bX. On trouvera de nombreux exemples d’usage de cette notation dans les chapitres consacrés, notamment, à la régression linéaire ou à la régression logistique.

De la même manière, l’opérateur | (pipe) utilisé par l’extension lattice joue aussi un rôle très important dans la rédaction de modèles multi-niveaux, où il sert à indiquer les variables à pentes ou à coefficients aléatoires. Ces modèles sont présentés dans un chapitre dédié.

Structures conditionnelles

La version originale de ce chapitre a été écrite par Ewen Gallic dans le cadre de son support de cours d’Ewen Gallic intitulé Logiciel R et programmation, chapitre 4 Boucles et calculs vectoriels.

Il existe deux sortes de boucles dans R. Celles pour lesquelles les itérations continuent tant qu’une condition n’est pas invalidée (while), et celles pour lesquelles le nombre d’itérations est défini au moment de lancer la boucle (for).

Avant de présenter chacune de ces fonctions, il est nécessaire de préciser que les boucles ne sont pas le point fort de R. Dès que l’on souhaite appliquer une fonction à chaque élément d’un vecteur, et/ou que le résultat de chaque itération ne dépend pas de l’itération précédente, il est préférable de vectoriser les calculs (voir le chapitre sur la vectorisation).

Les boucles avec while

Quand on souhaite répéter un calcul tant qu’une condition est satisfaite, on utilise la fonction while, avec la syntaxte suivante :

while (condition) {
  instruction
}

avec condition une valeur logique (TRUE ou FALSE), et instruction du code, qui peut être entouré d’accolades si on souhaite évaluer plusieurs instructions.

Le code instruction sera répété tant que condition est vrai. Prenons l’exemple d’une plante qui mesure 10 centimètres et qui va grandir de 10 % tous les ans jusqu’à atteindre 2 mètres.

taille <- 0.10
duree <- 0
while (taille < 2) {
  taille <- taille * 1.1
  duree <- duree + 1
}
message(glue::glue("La plante a atteint {round(taille, 1)} mètres en {duree} années."))
La plante a atteint 2.1 mètres en 32 années.

Les boucles avec for

Quand on connaît le nombre d’itérations à l’avance, on peut utiliser la boucle for. La syntaxe est la suivante :

for (variable in vector) {
  instruction
}

avec variable le nom d’une variable locale à la boucle for, vector un vecteur à n éléments définissant les valeurs que prendra variable pour chacun des n tours, et instruction le code à exécuter à chaque itération.

On peut utiliser for pour remplir les éléments d’une liste, ou d’un vecteur.

# Mauvaise manière
resultat <- NULL
for (i in 1:3) {
  resultat[i] <- i
}
resultat
[1] 1 2 3

À chaque itération, R doit trouver le vecteur de destination en mémoire, créer un nouveau vecteur qui permettra de contenir plus de données, copier données depuis l’ancien vecteur pour les insérer dans le nouveau, et enfin supprimer l’ancien vecteur (Ross, 2014). C’est une opération coûteuse en temps. Un moyen de rendre cette allocation plus efficace est de créer a priori le vecteur ou la liste en le remplissant avec des données manquantes. Ainsi, R n’aura pas besoin de ré-allouer la mémoire à chaque itération.

# Manière plus économique
resultat <- rep(NA, 3)
for (i in 1:3) {
  resultat[i] <- i
}
resultat
[1] 1 2 3

Les conditions

On peut soumettre l’exécution de codes en R à conditions que certaines conditions soient honorées.

Les instructions if … else

Les instructions if et else fournissent un moyen d’exécuter du code si une condition est respectée ou non. La syntaxe prend deux formes :

# Première forme (pas de code si condition == FALSE)
if (condition) {instruction si vrai}

# Seconde forme
if (condition) {instruction si vrai} else {instruction si faux}

avec condition un logique, instruction si vrai le code à exécuter si la condition est vérifiée et instruction si faux le code à exécuter si la condition n’est pas remplie. À nouveau, on peut avoir recours aux accolades pour créer des regroupements.

# Simple condition
x <- 2
if (x == 2) print("Hello")
[1] "Hello"
x <- 3
if (x == 2) print("Hello")

# Avec des instructions dans le cas contraire
if (x == 2) print("Hello") else print("x est différent de 2")
[1] "x est différent de 2"
if (x == 2) {
  print("Hello")
} else {
  x <- x - 1
  print(paste0("La nouvelle valeur de x : ", x))
}
[1] "La nouvelle valeur de x : 2"

Attention, lorsque l’on fait des regroupements et qu’on utilise la structure if et else, il est nécessaire d’écrire le mot else sur la même ligne que la parenthèse fermante du groupe d’instructions à réaliser dans le cas où la condition du if est vérifiée.

La fonction switch

Avec la fonction switch, on peut indiquer à R d’exécuter un code en fonction du résultat obtenu lors d’un test. La syntaxe est la suivante :

switch(valeur_test,
  cas_1 = {
    instruction_cas_1
  },
  cas_2 = {
    instruction_cas_2
  },
  ...
)

avec valeur_test un nombre ou une chaîne de caractères. Si valeur_test vaut cas_1, alors uniquement instruction_cas_1 sera évaluée, si valeur_test vaut cas_2, alors ce sera instruction_cas_2 qui le sera, et ainsi de suite. On peut rajouter une valeur par défaut en utilisant la syntaxte suivante :

switch(valeur_test,
  cas_1 = {
    instruction_cas_1
  },
  cas_2 = {
    instruction_cas_2
  },
  ...,
  {
    instruction_defaut
  }
)

Voici un exemple d’utilisation, issu de la page d’aide de la fonction.

centre <- function(x, type) {
  switch(type,
    mean = mean(x),
    median = median(x),
    trimmed = mean(x, trim = .1)
  )
}
x <- rcauchy(10)
centre(x, "mean")
[1] 0.4824179
centre(x, "median")
[1] 0.4950256
centre(x, "trimmed")
[1] 0.40101

L’instruction repeat … break

L’instruction repeat permet de répéter une expression. Il est nécessaire d’ajouter un test d’arrêt, à l’aide de l’instruction break.

i <- 1
repeat {
  i <- i + 1
  if (i == 3) break
}
i
[1] 3

L’instruction next

L’instruction next autorise de passer immédiatement à l’itération suivante d’une boucle for, while ou repeat.

result <- rep(NA, 10)
for (i in 1:10) {
  if (i == 5) next
  result[i] <- i
}
# Le 5e élément de result n'a pas été traité
result
 [1]  1  2  3  4 NA  6  7  8  9 10

Barre de progression

Lorsque l’exécution d’une boucle prend du temps, il peut être intéressant d’avoir une idée de l’état d’avancement des itérations. Pour cela, il est bien sûr possible d’afficher une valeur dans la console à chaque tour, chaque 10 tours, etc.

La fonction txtProgressBar de l’extension utils permet un affichage d’une barre de progression dans la console. Il suffit de lui fournir une valeur minimale et maximale, et de la mettre à jour à chaque itération. Le paramètre style autorise de surcroit à choisir un style pour la barre. Le style numéro 3 affiche un pourcentage de progression, et est utile lorsque d’autres résultats sont affichés dans la console lors de l’exécution de la boucle, dans la mesure où la barre est de nouveau affichée au complet dans la console si nécessaire.

Dans l’exemple qui suit, à chacun des dix tours, une pause de 0.1 seconde est effectuée, puis la barre de progression est mise à jour.

nb_tours <- 10
pb <- txtProgressBar(min = 1, max = nb_tours, style = 3)
for (i in 1:nb_tours) {
  Sys.sleep(0.1)
  setTxtProgressBar(pb, i)
}

  |                                                        
  |                                                  |   0%
  |                                                        
  |======                                            |  11%
  |                                                        
  |===========                                       |  22%
  |                                                        
  |=================                                 |  33%
  |                                                        
  |======================                            |  44%
  |                                                        
  |============================                      |  56%
  |                                                        
  |=================================                 |  67%
  |                                                        
  |=======================================           |  78%
  |                                                        
  |============================================      |  89%
  |                                                        
  |==================================================| 100%

Pour plus d’options, on pourra se référer à la fonction progress_bar de l’extension progress, présentée en détail sur https://r-pkg.org/pkg/progress.

Si l’exécution est vraiment longue, et qu’on est impatient de connaître les résultats, il existe de plus une fonction amusante dans l’extension beepr, qui porte le nom de beep. Plusieurs sons peuvent être utilisés (voir la page d’aide de la fonction).

library(beepr)
beep("mario")

Vectorisation

La version originale de ce chapitre a été écrite par Ewen Gallic dans le cadre de son support de cours d’Ewen Gallic intitulé Logiciel R et programmation, chapitre 4 Boucles et calculs vectoriels.

Les boucles sont des opérations lentes en R. Il est cependant possible, dans de nombreux cas, d’éviter de les employer, en ayant recours à la vectorisation : au lieu d’appliquer une fonction à un scalaire, on l’applique à un vecteur. En fait, nous avons déjà eu recours à maintes reprises aux calculs vectoriels. En effet, lorsque nous avons procédé à des additions, des multiplications, etc. sur des vecteurs, nous avons effectué des calculs vectoriels.

Empruntons un exemple à Burns (2011) : dans des langages comme le C, pour effectuer la somme des logarithmes naturels des n premiers entiers, voici une manière de faire :

# Somme des logarithmes des 10 premiers entiers
somme_log <- 0
for (i in seq_len(10)) {
  somme_log <- somme_log + log(i)
}
somme_log
[1] 15.10441

Il est possible d’obtenir le même résultat, à la fois d’une manière plus élégante, mais surtout plus efficace en vectorisant le calcul :

sum(log(seq_len(10)))
[1] 15.10441

Derrière ce code, la fonction log applique la fonction logarithme sur toutes les valeurs du vecteur donné en paramètre. La fonction sum, quant à elle, se charge d’additionner tous les éléments du vecteur qui lui est donné en paramètre. Ces deux fonctions utilisent la vectorisation, mais d’une manière différente : la fonction log applique une opération à chaque élément d’un vecteur, tandis que la fonction sum produit un résultat basé sur l’ensemble du vecteur. L’avantage d’utiliser des fonctions vectorielles plutôt que d’écrire une boucle pour effectuer le calcul, est que ces premières font appel à des fonctions rédigées en C ou FORTRAN, qui utilisent aussi des boucles, mais comme ce sont des langages compilés et non pas interprétés, les itérations sont réalisées dans un temps réduit.

Il existe des fonctions, rédigées en C qui effectuent des boucles for. On leur donne souvent le nom de “fonctions de la famille apply”. Il ne s’agit pas de la vectorisation, mais ces fonctions sont souvent mentionnées dès que l’on parle de ce sujet. Ce sont des fonctionnelles qui prennent une fonction en input et retournent un vecteur en output (Wickham, 2014). Ces fonctions sont très utilisées, mais elles souffrent d’un manque d’uniformité. En effet, elles ont été rédigées par des personnes différentes, ayant chacune leur convention. L’extension plyr remédie à ce problème, et ajoute par la même occasion des fonctions supplémentaires, pour couvrir plus de cas que les “fonctions de la famille apply”.

Nous allons donc présenter dans un premier temps les fonctions du package plyr. Les fonctions du même type du package base seront tout de même présentées par la suite.

Les fonctions de l’extension plyr

Les fonctions que nous allons aborder dans cette section possèdent des noms faciles à se remémorer : la première lettre correspond au format d’entrée des données, la seconde au format de sortie souhaité, et la fin du nom se termine par le suffixe ply. Ainsi, la fonction llpply prend en entrée une liste, effectue une opération sur les éléments, et retourne une liste (Anderson, 2012).

Les différentes fonctions que nous allons passer en revue sont consignées dans le tableau ci-après, où les lignes correspondent aux formats d’entrée, et les lignes aux formats de sortie. Pour y avoir accès, il faut charger le package :

library(plyr)
Format de sortie
array data.frame list
Format d’entée array aaply adply alply
data.frame daply ddply dlply
list laply ldply llply

Il est possible d’avoir plusieurs paramètres en input au lieu d’un seul objet. Les fonctions mlply, mdply et maply. Si à la place du m, la première lettre est un r, il s’agit alors de fonction de réplications. Enfin, si la seconde lettre est un trait de soulignement (_), alors le résultat retourné n’est pas affiché (le code utilise la fonction invisible.

Tous les paramètres de ces fonctions commencent par un point (.), afin d’éviter des incompatibilités avec la fonction à appliquer.

Array en input : a*ply

Les fonctions aaply, adply et alply appliquent une fonction à chaque portion d’un array et ensuitent joignent le résultat sous forme d’un array, d’un data.frame ou d’une list respectivement.

Un array peut être vu comme un vecteur à plusieurs dimensions. Comme pour un vecteur, toutes les valeurs doivent être du même type. Un vecteur n’est finalement qu’un array à une seule dimension. De même, un array à deux dimensions correspond à ce qu’on appelle usuelement une matrice.

Le paramètre .margins détermine la manière de découper le tableau. Il y en a quatre pour un tableau en deux dimensions :

  1. .margins = 1 : par lignes ;
  2. .margins = 2 : par colonnes ;
  3. .margins = c(1,2) : par cellule ;
  4. .margins = c() : ne pas faire de découpement.

Pour un tableau en trois dimensions, il y a trois découpages possibles en deux dimensions, trois en une dimension et une en zéro dimension (voir (Wickham, 2011)) au besoin.

tableau <- array(
  1:24,
  dim = c(3, 4, 2),
  dimnames = list(
    ligne = letters[1:3],
    colonne = LETTERS[1:4],
    annee = 2001:2002
  )
)
tableau
, , annee = 2001

     colonne
ligne A B C  D
    a 1 4 7 10
    b 2 5 8 11
    c 3 6 9 12

, , annee = 2002

     colonne
ligne  A  B  C  D
    a 13 16 19 22
    b 14 17 20 23
    c 15 18 21 24
# La moyenne des valeurs pour chaque ligne
aaply(tableau, 1, mean) # résultat sous forme de tableau
   a    b    c 
11.5 12.5 13.5 
adply(tableau, 1, mean) # résultat sous forme de data.frame
ligne V1
a 11.5
b 12.5
c 13.5
alply(tableau, 1, mean) # résultat sous forme de liste
$`1`
[1] 11.5

$`2`
[1] 12.5

$`3`
[1] 13.5

attr(,"split_type")
[1] "array"
attr(,"split_labels")
  ligne
1     a
2     b
3     c
# La moyenne des valeurs pour chaque colonne
# en ne simplifiant pas le résultat
aaply(tableau, 2, mean, .drop = FALSE)
1
A 8
B 11
C 14
D 17
# Par lignes et colonnes
aaply(tableau, c(1, 2), mean)
A B C D
a 7 10 13 16
b 8 11 14 17
c 9 12 15 18
adply(tableau, c(1, 2), mean)
ligne colonne V1
a A 7
b A 8
c A 9
a B 10
b B 11
c B 12
a C 13
b C 14
c C 15
a D 16
b D 17
c D 18
# Avec une fonction définie par l'utilisateur
standardise <- function(x) (x - min(x)) / (max(x) - min(x))
# Standardiser les valeurs par colonne
aaply(tableau, 2, standardise)
, , annee = 2001

       ligne
colonne a          b         c
      A 0 0.07142857 0.1428571
      B 0 0.07142857 0.1428571
      C 0 0.07142857 0.1428571
      D 0 0.07142857 0.1428571

, , annee = 2002

       ligne
colonne         a         b c
      A 0.8571429 0.9285714 1
      B 0.8571429 0.9285714 1
      C 0.8571429 0.9285714 1
      D 0.8571429 0.9285714 1

Data.frame en input : d*ply

Dans le cas de l’analyse d’enquêtes, on utilise principalement des tableaux de données ou data.frame. Aussi, la connaissance des fonction daply, ddply et dlply peut être utile. En effet, elles sont très utiles pour appliquer des fonctions à des groupes basés sur des combinaisons de variables, même si dans la majorité des cas il est maintenant plus facile de passer par les extensions dplyr ou data.table avec les opérations groupées (voir la section sur groub_by de dplyr ou encore celle sur le paramètre by de data.table.

Avec les fonctions d*ply, il est nécessaire d’indiquer quelles variables, ou fonctions de variables on souhaite utiliser, en l’indiquant au paramètre .variables. Elles peuvent être contenue dans le data frame fourni au paramètre .data, ou bien provenir de l’environnement global. R cherchera dans un premier temps si la variable est contenue dans le data.frame et, s’il ne trouve pas, ira chercher dans l’environnement global.

Pour indiquer que l’on désire faire le regroupement selon une variable – mettons variable_1 – il faudra fournir l’expression .(variable_1) au paramètre .variables. Si on souhaite effectuer les regroupement selon les interactions de plusieurs variables – variable_1, variable_2 et variable_3, il faut alors utiliser l’expression suivante : .(variable_1, variable_2, variable_3).

chomage <- data.frame(
  region = rep(c(rep("Bretagne", 4), rep("Corse", 2)), 2),
  departement = rep(c(
    "Cotes-d'Armor", "Finistere",
    "Ille-et-Vilaine", "Morbihan",
    "Corse-du-Sud", "Haute-Corse"
  ), 2),
  annee = rep(c(2011, 2010), each = 6),
  ouvriers = c(
    8738, 12701, 11390, 10228, 975, 1297,
    8113, 12258, 10897, 9617, 936, 1220
  ),
  ingenieurs = c(
    1420, 2530, 3986, 2025, 259, 254,
    1334, 2401, 3776, 1979, 253, 241
  )
)
chomage
region departement annee ouvriers ingenieurs
Bretagne Cotes-d’Armor 2011 8738 1420
Bretagne Finistere 2011 12701 2530
Bretagne Ille-et-Vilaine 2011 11390 3986
Bretagne Morbihan 2011 10228 2025
Corse Corse-du-Sud 2011 975 259
Corse Haute-Corse 2011 1297 254
Bretagne Cotes-d’Armor 2010 8113 1334
Bretagne Finistere 2010 12258 2401
Bretagne Ille-et-Vilaine 2010 10897 3776
Bretagne Morbihan 2010 9617 1979
Corse Corse-du-Sud 2010 936 253
Corse Haute-Corse 2010 1220 241
# Total chomeurs en Bretagne et en Corse pour les années 2010 et 2011
# sous forme de data.frame
ddply(chomage, .(annee), summarise, total_chomeurs = sum(ouvriers + ingenieurs))
annee total_chomeurs
2010 53025
2011 55803
# sous forme de array
daply(chomage, .(annee), summarise, total_chomeurs = sum(ouvriers + ingenieurs))
$`2010`
[1] 53025

$`2011`
[1] 55803
# sous forme de list
dlply(chomage, .(annee), summarise, total_chomeurs = sum(ouvriers + ingenieurs))
$`2010`
  total_chomeurs
1          53025

$`2011`
  total_chomeurs
1          55803

attr(,"split_type")
[1] "data.frame"
attr(,"split_labels")
  annee
1  2010
2  2011
# Total chomeurs pour les années 2010 et 2011, par région du data frame
ddply(chomage, .(annee, region), summarise,
  total_chomeurs = sum(ouvriers + ingenieurs)
)
annee region total_chomeurs
2010 Bretagne 50375
2010 Corse 2650
2011 Bretagne 53018
2011 Corse 2785
# Nombre d'observations pour chaque groupe
ddply(chomage, .(annee, region), nrow)
annee region V1
2010 Bretagne 4
2010 Corse 2
2011 Bretagne 4
2011 Corse 2
# En utilisant une fonction définie par l'utilisateur
ddply(chomage, .(annee, region), function(x) {
  moy_ouvriers <- mean(x$ouvriers)
  moy_ingenieurs <- mean(x$ingenieurs)
  data.frame(moy_ouvriers = moy_ouvriers, moy_ingenieurs = moy_ingenieurs)
})
annee region moy_ouvriers moy_ingenieurs
2010 Bretagne 10221.25 2372.50
2010 Corse 1078.00 247.00
2011 Bretagne 10764.25 2490.25
2011 Corse 1136.00 256.50

List en input : l*ply

Les fonctions du type l*ply prennent une liste en entrée. Il n’y a donc pas de paramétrage à effectuer pour choisir un découpage, il est déjà fait.

set.seed(1)
liste <- list(normale = rnorm(10), logiques = c(TRUE, TRUE, FALSE), x = c(0, NA, 3))
# Obtenir la longueur de chaque élément de la liste
laply(liste, length)
[1] 10  3  3
ldply(liste, length)
.id V1
normale 10
logiques 3
x 3
llply(liste, length)
$normale
[1] 10

$logiques
[1] 3

$x
[1] 3
# Calculer la moyenne pour chaque élément
unlist(llply(liste, mean, na.rm = TRUE))
  normale  logiques         x 
0.1322028 0.6666667 1.5000000 
# Appliquer une fonction définie par l'utilisateur
llply(liste, function(x, y) x / mean(x, na.rm = TRUE) + y, y = 2)
$normale
 [1] -2.7385827  3.3891033 -4.3208096 14.0669232  4.4924421
 [6] -4.2061356  5.6869803  7.5847895  6.3552892 -0.3099997

$logiques
[1] 3.5 3.5 2.0

$x
[1]  2 NA  4

Calcul parallèle

En utilisant plusieurs processeurs, on peut effectuer des calculs parallèles, ce qui accélère les calculs dans certains cas. En effet, quand il est possible de fractionner les opérations à effectuer en morceaux, on peut en réaliser une partie sur un processeur, une autre sur un second processeur, et ainsi de suite. Les résultats obtenus sont ensuite rassemblés avant d’être retournés. Le package doMC (ou doSMP sur Windows) peut être chargé pour utiliser la fonction de calcul parallèle proposé par les fonctions **ply. Il suffit de préciser le nombre de coeurs souhaité en faisant appel à la fonction registerDoMC, et de fixer la valeur TRUE au paramètre .parallel de la fonction **ply.

Les fonctions de la famille apply du package base

Le tableau ci-après recense les fonctions principales de la famille apply du package base.

Fonction Input Output
apply Matrice ou tableau Vecteur ou tableau ou liste
lapply Liste ou vecteur Liste
sapply Liste ou vecteur Vecteur ou matrice ou liste
vapply Liste ou vecteur Vecteur ou matrice ou liste
tapply Tableau et facteurs Tableau ou liste
mapply Listes et/ou vecteurs Vecteur ou matrice ou liste

La fonction lapply

La fonction lapply applique à chaque élément du premier paramètre qui lui est donné une fonction indiquée en second paramètre et retourne le résultat sous forme de liste. La syntaxe est la suivante :

lapply(X, FUN, ...)

avec X la liste ou le vecteur donné en paramètre sur lequel on désire appliquer la fonction FUN. La paramètre ... permet de fournir des paramètres à une fonction imbriquée, en l’occurance à celle que l’on souhaite appliquer à tous les éléments de X.

liste <- list(normale = rnorm(10), logiques = c(TRUE, TRUE, FALSE), x = c(0, NA, 3))

# Obtenir la liste des longueurs de chaque élément
lapply(liste, length)
$normale
[1] 10

$logiques
[1] 3

$x
[1] 3
# Calculer la moyenne pour chaque élément
lapply(liste, mean, na.rm = TRUE)
$normale
[1] 0.248845

$logiques
[1] 0.6666667

$x
[1] 1.5

On peut créer une fonction à l’intérieur de l’appel à lapply. Le premier paramètre est nécessairement un élément du vecteur auquel on souhaite appliquer la fonction.

lapply(liste, function(x) x / mean(x, na.rm = TRUE))
$normale
 [1]  6.07519277  1.56661087 -2.49649643 -8.89991820
 [5]  4.52060941 -0.18056868 -0.06506164  3.79286833
 [9]  3.30013177  2.38663180

$logiques
[1] 1.5 1.5 0.0

$x
[1]  0 NA  2
# Si la fonction doit posséder plusieurs paramètres
lapply(liste, function(x, y) x / mean(x, na.rm = TRUE) + y, y = 2)
$normale
 [1]  8.0751928  3.5666109 -0.4964964 -6.8999182  6.5206094
 [6]  1.8194313  1.9349384  5.7928683  5.3001318  4.3866318

$logiques
[1] 3.5 3.5 2.0

$x
[1]  2 NA  4

On peut appliquer la lapply sur des tableaux de données, dans la mesure où ces derniers sont des listes. Cela s’avère pratique pour réaliser des opérations pour chaque colonne d’un tableau de données. Afin de prendre moins de place dans l’affichage, l’exemple suivant utilise la fonction unlist pour aplatir la liste obtenue.

data(cars)

# Afficher le type de chaque colonne de la data frame "cars"
unlist(lapply(cars, class))
    speed      dist 
"numeric" "numeric" 
# Calculer la moyenne pour chaque colonne
unlist(lapply(cars, mean))
speed  dist 
15.40 42.98 

Attention, ce qui suit relève plus d’un tour de passe-passe que de la programmation élégante.

Si la fonction que l’on souhaite appliquer aux éléments de notre vecteur retourne un vecteur ligne de même longueur pour chaque élément, la fonction do.call peut devenir un outil très pratique pour créer une data frame. Voyons-le à travers un exemple.

l <- lapply(1:3, function(x) cbind(valeur = x, lettre = LETTERS[x]))
l
[[1]]
     valeur lettre
[1,] "1"    "A"   

[[2]]
     valeur lettre
[1,] "2"    "B"   

[[3]]
     valeur lettre
[1,] "3"    "C"   
data.frame(do.call("rbind", l))
valeur lettre
1 A
2 B
3 C

L’appel de do.call("rbind", x) revient à faire rbind(x[[1]], x[[2]], ..., x[[n]]) avec x une liste de taille n.

La fonction sapply

La fonction sapply applique une fonction aux éléments d’un vecteur ou d’une liste et peut retourner un vecteur, une liste ou une matrice. Elle possède la syntaxe suivante :

sapply(X, FUN, simplify, USE.NAMES)

X est le vecteur ou la liste auquel on souhaite appliquer la fonction FUN. Lorsque simplify vaut FALSE, le résultat est retourné sous forme de liste, exactement comme lapply (la fonction sapply s’appuie sur la fonction lapply). Lorsque simplify vaut TRUE (par défaut), le résultat est retourné dans une forme simplifiée, si cela est possible. Si tous les éléments retournés par la fonction FUN sont des scalaires, alors sapply retourne un vecteur ; sinon, si les éléments retournés ont la même taille, sapply retourne une matrice avec une colonne pour chaque élément de X auquel la fonction FUN est appliquée. Le paramètre USE.NAMES, quand il vaut TRUE (par défaut), et si X est de type character, utilise X comme nom pour le résultat, à moins que le résultat possède déjà des noms.

(x <- list(a = 1:10, beta = exp(-3:3), logic = c(TRUE, FALSE, FALSE, TRUE)))
$a
 [1]  1  2  3  4  5  6  7  8  9 10

$beta
[1]  0.04978707  0.13533528  0.36787944  1.00000000
[5]  2.71828183  7.38905610 20.08553692

$logic
[1]  TRUE FALSE FALSE  TRUE
# Application de la fonction quantile() à chaque élément
# pour obtenir la médiane et les quartiles
# Avec lapply()
lapply(x, quantile)
$a
   0%   25%   50%   75%  100% 
 1.00  3.25  5.50  7.75 10.00 

$beta
         0%         25%         50%         75%        100% 
 0.04978707  0.25160736  1.00000000  5.05366896 20.08553692 

$logic
  0%  25%  50%  75% 100% 
 0.0  0.0  0.5  1.0  1.0 
# Avec sapply
sapply(x, quantile)
a beta logic
0% 1.00 0.0497871 0.0
25% 3.25 0.2516074 0.0
50% 5.50 1.0000000 0.5
75% 7.75 5.0536690 1.0
100% 10.00 20.0855369 1.0
# Exemple avec USE.NAMES
sapply(LETTERS[1:3], nchar)
A B C 
1 1 1 
sapply(LETTERS[1:3], nchar, USE.NAMES = FALSE)
[1] 1 1 1

La fonction vapply

La fonction vapply est similaire à sapply, mais elle possède un type de valeurs spécifié, ce qui peut rendre l’utilisation plus sûre (et parfois plus rapide). Lorsqu’on lui fournit un data.frame, vapply retourne le même résultat que sapply. Cependant, quand on lui fournit une liste vide, vapply retourne un vecteur logique de longueur nulle (ce qui est plus sensé que la liste vide que returne sapply).

vapply(X, FUN, FUN.VALUE, ..., USE.NAMES)

avec X, FUN, ... et USE.NAMES les mêmes paramètres que pour sapply. Le paramètre FUN.VALUE doit être un vecteur, un masque pour la valeur retournée par la fonction de FUN.

# Retourner le vecteur
sapply(cars, is.numeric)
speed  dist 
 TRUE  TRUE 
vapply(cars, is.numeric, FUN.VALUE = logical(1))
speed  dist 
 TRUE  TRUE 
# Avec la liste vide
sapply(list(), is.numeric)
list()
vapply(list(), is.numeric, FUN.VALUE = logical(1))
logical(0)

La fonction apply

La fonction apply possède la syntaxe suivante :

apply(X, MARGIN, FUN, ...)

avec X une matrice ou un tableau, MARGIN indiquant si on souhaite appliquer la fonction FUN aux lignes (MARGIN = 1) ou aux colonnes (MARGIN = 2), et ... des paramètres supplémentaires éventuels à passer à la fonction FUN.

(X <- matrix(1:9, ncol = 3))
1 4 7
2 5 8
3 6 9
# Somme par ligne
apply(X, MARGIN = 1, sum)
[1] 12 15 18
# Somme par colonne
apply(X, MARGIN = 2, sum)
[1]  6 15 24
# Fonction définie par l'utilisateur
apply(X, MARGIN = 1, function(x) sum(x) / sum(X))
[1] 0.2666667 0.3333333 0.4000000

La fonction tapply

La fonction tapply s’applique à chaque cellule d’un tableau, sur des regroupements définis par les variables catégorielles fournies. La syntaxe est la suivante :

tapply(X, INDEX, FUN, ..., simplify)

avec X le tableau de données, INDEX une liste d’un ou plusieurs facteurs, chacun de même taille que X. Le paramètre FUN renseigne la fonction que l’on souhaite appliquer. Si simplify vaut FALSE, le résultat est un tableau de mode list. Sinon (par défaut), le résultat est un tableau de scalaires.

data(iris)
head(iris)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
5.1 3.5 1.4 0.2 setosa
4.9 3.0 1.4 0.2 setosa
4.7 3.2 1.3 0.2 setosa
4.6 3.1 1.5 0.2 setosa
5.0 3.6 1.4 0.2 setosa
5.4 3.9 1.7 0.4 setosa
# Moyenne de la longueur des sépales par espèce
tapply(iris$Sepal.Length, iris$Species, mean)
    setosa versicolor  virginica 
     5.006      5.936      6.588 
# Pour retourner le résultat sous forme de liste
tapply(iris$Sepal.Length, iris$Species, mean, simplify = FALSE)
$setosa
[1] 5.006

$versicolor
[1] 5.936

$virginica
[1] 6.588

La fonction mapply

La fonction mapply applique une fonction à plusieurs listes ou vecteurs. La syntaxe est la suivante :

mapply(FUN, ..., MoreArgs, SIMPLIFY, USE.NAMES)

avec FUN la fonction à appliquer aux vecteurs ou listes fournies (grâce à ...), MoreArgs une liste de paramètres supplémentaires à fournir à la fonction à appliquer. Les paramètres SIMPLIFY et USE.NAMES ont le même usage que pour la fonction sapply.

(l1 <- list(a = c(1:5), b = c(6:10)))
$a
[1] 1 2 3 4 5

$b
[1]  6  7  8  9 10
(l2 <- list(c = c(11:15), d = c(16:20)))
$c
[1] 11 12 13 14 15

$d
[1] 16 17 18 19 20
# La somme des éléments correspondants de l1 et l2
mapply(sum, l1$a, l1$b, l2$c, l2$d)
[1] 34 38 42 46 50
# Attention au recyclage silencieux !
(l1 <- list(a = c(1:5), b = c(6:20)))
$a
[1] 1 2 3 4 5

$b
 [1]  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
mapply(sum, l1$a, l1$b, l2$c, l2$d)
 [1] 34 38 42 46 50 39 43 47 51 55 44 48 52 56 60

La fonction Vectorize

La fonction Vectorize permet de convertir une fonction scalaire en une fonction vectorielle. Attention, cela ne permet pas d’améliorer la rapidité d’exécution du code. Par contre, son utilisation assez intuitive permet de gagner du temps. Il s’agit donc de faire l’arbitrage entre le temps passé à trouver un moyen élégant et efficace pour effectuer une opération en passant par de réels calculs vectoriels et le gain d’exécution que ce calcul vectoriel apporte vis-à-vis d’une boucle. La syntaxe de la Vectorize est la suivante :

Vectorize(FUN, vectorize.args, SIMPLIFY, USE.NAMES)

avec FUN une fonction à appliquer, vectorize.args un vecteur de paramètres (de type caractère) qui devraient être vectorisés (par défaut, tous les paramètre de FUN). Les paramètres SIMPLIFY et USE.NAMES on le même emploi que dans la fonction sapply.

f <- function(x = 1:3, y) c(x, y)
# On "vectorise" la fonction f
vf <- Vectorize(f, SIMPLIFY = FALSE)
f(1:3, 1:3)
[1] 1 2 3 1 2 3
vf(1:3, 1:3)
[[1]]
[1] 1 1

[[2]]
[1] 2 2

[[3]]
[1] 3 3
# Vectorise seulement y, pas x
vf(y = 1:3)
[[1]]
[1] 1 2 3 1

[[2]]
[1] 1 2 3 2

[[3]]
[1] 1 2 3 3

Expressions régulières

Les expressions régulières sont un outils pour rechercher / remplacer dans des chaînes de texte. Il est préférable d’avoir lu au préalable le chapitre dédié à la manipulation de texte.

Pour une introduction (en anglais) aux expressions régulières, on pourra se référer au chapitre Strings de l’ouvrage R for Data Science de Garrett Grolemund et Hadley Wickham (http://r4ds.had.co.nz/strings.html).

Pour aller plus loin, le site de l’extension stringr propose une présentation détaillée (en anglais) de la syntaxe des expressions régulières (http://stringr.tidyverse.org/articles/regular-expressions.html).

Pour des besoins plus pointus, on pourra aussi utiliser l’extension stringi sur laquelle est elle-même basée stringr.

R Markdown : les rapports automatisés

La version originale de ce chapitre a été écrite par Julien Barnier dans le cadre de son Introduction à R et au tidyverse.

L’extension rmarkdown permet de générer des documents de manière dynamique en mélangeant texte mis en forme et résultats produits par du code R. Les documents générés peuvent être au format HTML, PDF, Word, et bien d’autres1. C’est donc un outil très pratique pour l’exportation, la communication et la diffusion de résultats d’analyse.

Le présent document a lui-même été généré à partir de fichiers R Markdown.

rmarkdown ne fait pas partie du tidyverse, mais elle est installée et chargée par défaut par RStudio2.

Rapport rapide à partir d’un script R

Si vos analyses sont présentes dans un script R et que ce script contient tout le nécessaire pour la réalisation de votre analyse (i.e. chargement des données et des packages requis), vous pouvez très facilement réaliser un rapport rapide au format HTML, Word ou PDF, contenant à la fois votre code et les sorties associées.

Il suffit de cliquer sur l’icône compile report dans le quadrant supérieur gauche.

position de l’icône compile report
Position de l’icône compile report

De manière alternative, si votre script s’intitule analyses.R, vous pouvez exécuter la commande suivante :

rmarkdown::render("analyses.R")

Pour plus d’informations sur les options disponibles, vous pouvez également consulter https://rmarkdown.rstudio.com/articles_report_from_r_script.html.

Un premier exemple

Voici un exemple de document R Markdown minimal :

---
title: "Test R Markdown"
---


*R Markdown* permet de mélanger :

- du texte libre mis en forme
- des blocs de code R

Les blocs de code sont exécutés et leur résultat affiché, par exemple :

```{r}
mean(mtcars$mpg)
```

## Graphiques

On peut également inclure des graphiques :

```{r}
plot(mtcars$hp, mtcars$mpg)
```

Ce document peut être compilé sous différents formats. Lors de cette étape, le texte est mis en forme, les blocs de code sont exécutés, leur résultat ajouté au document, et le tout est transformé dans un des différents formats possibles.

Voici le rendu du document précédent au format HTML :

Rendu HTML
Rendu HTML

Le rendu du même document au format PDF :

Rendu PDF
Rendu PDF

Et le rendu au format Word :

Rendu docx
Rendu docx

Les avantages de ce système sont nombreux :

  • le code et ses résultats ne sont pas séparés des commentaires qui leur sont associés
  • le document final est reproductible
  • le document peut être très facilement régénéré et mis à jour, par exemple si les données source ont été modifiées.

Créer un nouveau document

Un document R Markdown est un simple fichier texte enregistré avec l’extension .Rmd.

Sous RStudio, on peut créer un nouveau document en allant dans le menu File puis en choisissant New file puis R Markdown…. La boîte de dialogue suivante s’affiche :

Création d’un document R Markdown
Création d’un document R Markdown

On peut indiquer le titre, l’auteur du document ainsi que le format de sortie par défaut (il est possible de modifier facilement ses éléments par la suite). Plutôt qu’un document classique, on verra plus loin qu’on peut aussi choisir de créer une présentation sous forme de slides (entrée Presentation) ou de créer un document à partir d’un modèle (Entrée From Template).

Un fichier comportant un contenu d’exemple s’affiche alors. Vous pouvez l’enregistrer où vous le souhaitez avec une extension .Rmd.

Élements d’un document R Markdown

Un document R Markdown est donc un fichier texte qui ressemble à quelque chose comme ça :

---
title: "Titre"
author: "Prénom Nom"
date: "10 avril 2017"
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

## Introduction

Ceci est un document RMarkdown, qui mélange :

- du texte balisé selon la syntaxe Markdown
- des bouts de code R qui seront exécutés

Le code R se présente de la manière suivante :

```{r}
summary(cars)
```

## Graphiques

On peut aussi inclure des graphiques, par exemple :

```{r}
plot(pressure)
```

En-tête (préambule)

La première partie du document est son en-tête. Il se situe en tout début de document, et est délimité par trois tirets (---) avant et après :

---
title: "Titre"
author: "Prénom Nom"
date: "10 avril 2017"
output: html_document
---

Cet en-tête contient les métadonnées du document, comme son titre, son auteur, sa date, plus tout un tas d’options possibles qui vont permettre de configurer ou personnaliser l’ensemble du document et son rendu. Ici, par exemple, la ligne output: html_document indique que le document généré doit être au format HTML.

Texte du document

Le corps du document est constitué de texte qui suit la syntaxe Markdown. Un fichier Markdown est un fichier texte contenant un balisage léger qui permet de définir des niveaux de titres ou de mettre en forme le texte. Par exemple, le texte suivant :

Ceci est du texte avec *de l'italique* et **du gras**.

On peut définir des listes à puces :

- premier élément
- deuxième élément

Génèrera le texte mis en forme suivant :

Ceci est du texte avec de l’italique et du gras.

On peut définir des listes à puces :

  • premier élément
  • deuxième élément

On voit que des mots placés entre des astérisques sont mis en italique, des lignes qui commencent par un tiret sont transformés en liste à puce, etc.

On peut définir des titres de différents niveaux en faisant débuter une ligne par un ou plusieurs caractères # :

# Titre de niveau 1

## Titre de niveau 2

### Titre de niveau 3

Quand des titres ont été définis, si vous cliquez sur l’icône Show document outline totalement à droite de la barre d’outils associée au fichier R Markdown, une table des matières dynamique générée automatiquement à partir des titres présents dans le document s’affiche et vous permet de naviguer facilement dans celui-ci :

Table des matières dynamique
Table des matières dynamique

La syntaxe Markdown permet d’autres mises en forme, comme la possibilité d’insérer des liens ou des images. Par exemple, le code suivant :

[Exemple de lien](https://example.com)

Donnera le lien suivant :

Exemple de lien

Dans RStudio, le menu Help puis Markdown quick reference donne un aperçu plus complet de la syntaxe.

Blocs de code R

En plus du texte libre au format Markdown, un document R Markdown contient, comme son nom l’indique, du code R. Celui-ci est inclus dans des blocs (chunks) délimités par la syntaxe suivante :

```{r}
x <- 1:5
```

Comme cette suite de caractères n’est pas très simple à saisir, vous pouvez utiliser le menu Insert de RStudio et choisir R3, ou utiliser le raccourci clavier Ctrl+Alt+i.

Menu d’insertion d’un bloc de code
Menu d’insertion d’un bloc de code

Dans RStudio les blocs de code R sont en général affichés avec une couleur de fond légèrement différente pour les distinguer du reste du document.

Quand votre curseur se trouve dans un bloc, vous pouvez saisir le code R que vous souhaitez, l’exécuter, utiliser l’autocomplétion, exactement comme si vous vous trouviez dans un script R. Vous pouvez également exécuter l’ensemble du code contenu dans un bloc à l’aide du raccourci clavier Ctrl+Shift+Entrée.

Dans RStudio, par défaut, les résultats d’un bloc de code (texte, tableau ou graphique) s’affichent directement dans la fenêtre d’édition du document, permettant de les visualiser facilement et de les conserver le temps de la session 4.

Lorsque le document est compilé au format HTML, PDF ou docx, chaque bloc est exécuté tour à tour, et le résultat inclus dans le document final, qu’il s’agisse de texte, d’un tableau ou d’un graphique. Les blocs sont liés entre eux, dans le sens où les données importées ou calculées dans un bloc sont accessibles aux blocs suivants. On peut donc aussi voir un document R Markdown comme un script R dans lequel on aurait intercalé du texte libre au format Markdown.

À noter qu’avant chaque compilation, une nouvelle session R est lancée, ne contenant aucun objet. Les premiers blocs de code d’un document sont donc souvent utilisés pour importer des données, exécuter des recodages, etc.

Compiler un document (Knit)

On peut à tout moment compiler, ou plutôt tricoter (Knit), un document R Markdown pour obtenir et visualiser le document généré. Pour cela, il suffit de cliquer sur le bouton Knit et de choisir le format de sortie voulu :

Menu Knit
Menu Knit

Vous pouvez aussi utiliser le raccourci Ctrl+Shift+K pour compiler le document dans le dernier format utilisé.

Pour la génération du format PDF, vous devez avoir une installation fonctionnelle de LaTeX sur votre système. C’est en général le cas pour des ordinateurs Mac ou Linux, mais pas sous Windows : dans ce cas vous devrez installer une distribution comme MiKTeX.

Un onglet R Markdown s’ouvre dans la même zone que l’onglet Console et indique la progression de la compilation, ainsi que les messages d’erreur éventuels. Si tout se passe bien, Le document devrait s’afficher soit dans une fenêtre Viewer de RStudio (pour la sortie HTML), soit dans le logiciel par défaut de votre ordinateur.

Personnaliser le document généré

La personnalisation du document généré se fait en modifiant des options dans le préambule du document. RStudio propose néanmoins une petite interface graphique permettant de changer ces options plus facilement. Pour cela, cliquez sur l’icône en forme d’engrenage à droite du bouton Knit et choisissez Output Options…

Options de sortie R Markdown
Options de sortie R Markdown

Une boîte de dialogue s’affiche vous permettant de sélectionner le format de sortie souhaité et, selon le format, différentes options :

Dialogue d’options de sortie R Markdown
Dialogue d’options de sortie R Markdown

Pour le format HTML par exemple, l’onglet General vous permet de spécifier si vous voulez une table des matières, sa profondeur, les thèmes à appliquer pour le document et la coloration syntaxique des blocs R, etc. L’onglet Figures vous permet de changer les dimensions par défaut des graphiques générés.

Une option très intéressante pour les fichiers HTML, accessible via l’onglet Advanced, est l’entrée Create standalone HTML document. Si elle est cochée (ce qui est le cas par défaut), le document HTML généré contiendra en un seul fichier le code HTML mais aussi les images et toutes les autres ressources nécessaires à son affichage. Ceci permet de générer des fichiers (parfois assez volumineux) que vous pouvez transférer très facilement à quelqu’un par mail ou en le mettant en ligne quelque part. Si la case n’est pas cochée, les images et autres ressources sont placées dans un dossier à part.

Lorsque vous changez des options, RStudio va en fait modifier le préambule de votre document. Ainsi, si vous choisissez d’afficher une table des matières et de modifier le thème de coloration syntaxique, votre en-tête va devenir quelque chose comme :

---
title: "Test R Markdown"
output:
   html_document: 
     highlight: kate
     toc: yes
---

Vous pouvez modifier les options directement en éditant le préambule.

À noter qu’il est possible de spécifier des options différentes selon les formats, par exemple :

---
title: "Test R Markdown"
output:
  html_document: 
    highlight: kate
    toc: yes
  pdf_document: 
    fig_caption: yes
    highlight: kate
---

La liste complète des options possibles est présente sur le site de la documentation officielle (très complet et bien fait) et sur l’antisèche et le guide de référence, accessibles depuis RStudio via le menu Help puis Cheatsheets.

Options des blocs de code R

Il est également possible de passer des options à chaque bloc de code R pour modifier son comportement.

On rappelle qu’on bloc de code se présente de la manière suivante :

```{r}
x <- 1:5
```

Les options d’un bloc de code sont à placer à l’intérieur des accolades {r}.

Nom du bloc

La première possibilité est de donner un nom au bloc. Celui-ci est indiqué directement après le r :

{r nom_du_bloc}

Il n’est pas obligatoire de nommer un bloc, mais cela peut être utile en cas d’erreur à la compilation, pour identifier le bloc ayant causé le problème. Attention, on ne peut pas avoir deux blocs avec le même nom.

Options

En plus d’un nom, on peut passer à un bloc une série d’options sous la forme option = valeur. Voici un exemple de bloc avec un nom et des options :

```{r mon_bloc, echo = FALSE, warning = TRUE}
x <- 1:5
```

Et un exemple de bloc non nommé avec des options :

```{r echo = FALSE, warning = FALSE}
x <- 1:5
```

Une des options la plus utile est l’option echo. Par défaut echo vaut TRUE, et le bloc de code R est inséré dans le document généré, de cette manière :

x <- 1:5
print(x)
[1] 1 2 3 4 5

Mais si on positionne l’option echo=FALSE, alors le code R n’est plus inséré dans le document, et seul le résultat est visible :

[1] 1 2 3 4 5

Voici une liste de quelques unes des options disponibles :

Option Valeurs Description
echo TRUE/FALSE Afficher ou non le code R dans le document
eval TRUE/FALSE Exécuter ou non le code R à la compilation
include TRUE/FALSE Inclure ou non le code R et ses résultats dans le document
results “hide”/“asis”/“markup”/“hold” Type de résultats renvoyés par le bloc de code
warning TRUE/FALSE Afficher ou non les avertissements générés par le bloc
message TRUE/FALSE Afficher ou non les messages générés par le bloc

Il existe de nombreuses autres options décrites notamment dans guide de référence R Markdown (PDF en anglais).

Modifier les options

Il est possible de modifier les options manuellement en éditant l’en-tête du bloc de code, mais on peut aussi utiliser une petite interface graphique proposée par RStudio. Pour cela, il suffit de cliquer sur l’icône d’engrenage située à droite sur la ligne de l’en-tête de chaque bloc :

Menu d’options de bloc de code
Menu d’options de bloc de code

Vous pouvez ensuite modifier les options les plus courantes, et cliquer sur Apply pour les appliquer.

Options globales

On peut vouloir appliquer une option à l’ensemble des blocs d’un document. Par exemple, on peut souhaiter par défaut ne pas afficher le code R de chaque bloc dans le document final.

On peut positionner une option globalement en utilisant la fonction knitr::opts_chunk$set(). Par exemple, insérer knitr::opts_chunk$set(echo = FALSE) dans un bloc de code positionnera l’option echo = FALSE par défaut pour tous les blocs suivants.

En général, on place toutes ces modifications globales dans un bloc spécial nommé setup et qui est le premier bloc du document :

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

Par défaut RStudio exécute systématiquement le contenu du bloc setup avant d’exécuter celui d’un autre bloc.

Mise en cache des résultats

Compiler un document R Markdown peut être long, car il faut à chaque fois exécuter l’ensemble des blocs de code R qui le constituent.

Pour accélérer cette opération, R Markdown utilise un système de mise en cache : les résultats de chaque bloc sont enregistrés dans un fichier et à la prochaine compilation, si le code et les options du bloc n’ont pas été modifiés, c’est le contenu du fichier de cache qui est utilisé, ce qui évite d’exécuter le code R.

On peut activer ou désactiver la mise en cache des résultats pour chaque bloc de code avec l’option cache = TRUE ou cache = FALSE, et on peut aussi désactiver totalement la mise en cache pour le document en ajoutant knitr::opts_chunk$set(echo = FALSE) dans le premier bloc setup.

Ce système de cache peut poser problème par exemple si les données source changent : dans ce cas les résultats de certains blocs peuvent ne pas être mis à jour s’ils sont présents en cache. Dans ce cas, on peut vider le cache du document, ce qui forcera un recalcul de tous les blocs de code à la prochaine compilation. Pour cela, vous pouvez ouvrir le menu Knit et choisir Clear Knitr Cache… :

Menu Knit
Menu Knit

Rendu des tableaux

Tableaux croisés

Par défaut, les tableaux issus de la fonction table sont affichés comme ils apparaissent dans la console de R, en texte brut :

library(questionr)
data(hdv2003)
tab <- lprop(table(hdv2003$qualif, hdv2003$sexe))
tab
Homme Femme Total
Ouvrier specialise 47.29064 52.70936 100
Ouvrier qualifie 78.42466 21.57534 100
Technicien 76.74419 23.25581 100
Profession intermediaire 55.00000 45.00000 100
Cadre 55.76923 44.23077 100
Employe 16.16162 83.83838 100
Autre 36.20690 63.79310 100
Ensemble 44.82759 55.17241 100

On peut améliorer leur présentation en utilisant la fonction kable de l’extension knitr. Celle-ci fournit un formatage adapté en fonction du format de sortie. On aura donc des tableaux propres que ce soit en HTML, PDF ou aux formats traitements de texte :

library(knitr)
kable(tab)
Homme Femme Total
Ouvrier specialise 47.29064 52.70936 100
Ouvrier qualifie 78.42466 21.57534 100
Technicien 76.74419 23.25581 100
Profession intermediaire 55.00000 45.00000 100
Cadre 55.76923 44.23077 100
Employe 16.16162 83.83838 100
Autre 36.20690 63.79310 100
Ensemble 44.82759 55.17241 100

Différents arguments permettent de modifier la sortie de kable. digits, par exemple, permet de spécifier le nombre de chiffres significatifs à afficher dans les colonnes de nombres :

kable(tab, digits = 1)
Homme Femme Total
Ouvrier specialise 47.3 52.7 100
Ouvrier qualifie 78.4 21.6 100
Technicien 76.7 23.3 100
Profession intermediaire 55.0 45.0 100
Cadre 55.8 44.2 100
Employe 16.2 83.8 100
Autre 36.2 63.8 100
Ensemble 44.8 55.2 100

Pour une présentation plus avancée, on pourra également avoir recours à l’extenstion gtsummary et aux fonctions tbl_summary, tbl_svysummary et tbl_regression.

library(gtsummary)
theme_gtsummary_language("fr", decimal.mark = ",", big.mark = " ")
Setting `language: fr` theme
hdv2003 %>%
  dplyr::select(sexe, qualif) %>%
  tbl_summary(by = "sexe")
Caractéristique Homme, N = 8991 Femme, N = 1 1011
qualif
Ouvrier specialise 96 (13%) 107 (12%)
Ouvrier qualifie 229 (31%) 63 (6,9%)
Technicien 66 (8,9%) 20 (2,2%)
Profession intermediaire 88 (12%) 72 (7,9%)
Cadre 145 (20%) 115 (13%)
Employe 96 (13%) 498 (55%)
Autre 21 (2,8%) 37 (4,1%)
Manquant 158 189

1 Statistique présentée: n (%)

Tableaux de données et tris à plat

En ce qui concerne les tableaux de données (tibble ou data frame), l’affichage HTML par défaut se contente d’un affichage texte comme dans la console, très peu lisible dès que le tableau dépasse une certaine dimension.

Une alternative est d’utiliser la fonction paged_table, qui affiche une représentation HTML paginée du tableau :

rmarkdown::paged_table(hdv2003)
id age sexe nivetud poids occup qualif freres.soeurs clso relig trav.imp trav.satisf hard.rock lecture.bd peche.chasse cuisine bricol cinema sport heures.tv
1 28 Femme Enseignement superieur y compris technique superieur 2634.39822 Exerce une profession Employe 8 Oui Ni croyance ni appartenance Peu important Insatisfaction Non Non Non Oui Non Non Non 0.0
2 23 Femme NA 9738.39578 Etudiant, eleve NA 2 Oui Ni croyance ni appartenance NA NA Non Non Non Non Non Oui Oui 1.0
3 59 Homme Derniere annee d’etudes primaires 3994.10246 Exerce une profession Technicien 2 Non Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Non Non Non Non Oui 0.0
4 34 Homme Enseignement superieur y compris technique superieur 5731.66151 Exerce une profession Technicien 1 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 2.0
5 71 Femme Derniere annee d’etudes primaires 4329.09400 Retraite Employe 0 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 3.0
6 35 Femme Enseignement technique ou professionnel court 8674.69938 Exerce une profession Employe 5 Non Ni croyance ni appartenance Le plus important Equilibre Non Non Non Non Non Oui Oui 2.0
7 60 Femme Derniere annee d’etudes primaires 6165.80349 Au foyer Ouvrier qualifie 1 Oui Appartenance sans pratique NA NA Non Non Oui Oui Non Non Non 2.9
8 47 Homme Enseignement technique ou professionnel court 12891.64076 Exerce une profession Ouvrier qualifie 5 Non Ni croyance ni appartenance Peu important Insatisfaction Non Non Oui Oui Oui Non Non 1.0
9 20 Femme NA 7808.87206 Etudiant, eleve NA 4 Oui Appartenance sans pratique NA NA Non Non Non Non Non Oui Non 2.0
10 28 Homme Enseignement technique ou professionnel long 2277.16047 Exerce une profession Autre 2 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Non Oui Oui 2.0
11 65 Femme Enseignement superieur y compris technique superieur 704.32273 Retraite Employe 3 Oui Appartenance sans pratique NA NA Non Non Non Oui Oui Oui Non 1.0
12 47 Homme 2eme cycle 6697.86825 Exerce une profession Ouvrier qualifie 4 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Non Oui 0.0
13 63 Femme Derniere annee d’etudes primaires 7118.46585 Retraite Employe 1 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 4.0
14 67 Femme Enseignement technique ou professionnel court 586.77141 Exerce une profession NA 5 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Oui Non Non 1.0
15 76 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 11042.07745 Retraite NA 2 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Oui Non 3.0
16 49 Femme Enseignement technique ou professionnel court 9958.22873 Exerce une profession Employe 3 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Non Oui Non 0.0
17 62 Homme Enseignement superieur y compris technique superieur 4836.13931 Retraite Cadre 4 Non Pratiquant regulier NA NA Non Non Non Oui Oui Oui Oui 1.0
18 20 Femme NA 1551.48458 Etudiant, eleve NA 0 Non Appartenance sans pratique NA NA Non Non Non Oui Oui Oui Oui 3.0
19 70 Homme Derniere annee d’etudes primaires 3141.15717 Retraite Ouvrier specialise 2 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 1.0
20 39 Femme Enseignement technique ou professionnel court 27195.83782 Exerce une profession Ouvrier qualifie 5 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Oui Oui 2.7
21 30 Femme Enseignement technique ou professionnel court 14647.99834 Exerce une profession Employe 6 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Non Non 4.0
22 30 Homme Enseignement technique ou professionnel court 8128.06029 Exerce une profession Employe 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Non Non 6.0
23 37 Femme Enseignement technique ou professionnel court 1281.91563 Exerce une profession Employe 4 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Non Oui Oui 0.0
24 79 Femme Derniere annee d’etudes primaires 11663.33833 Autre inactif NA 11 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 7.0
25 20 Femme NA 8780.26142 Exerce une profession Ouvrier specialise 0 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Oui Oui 2.0
26 74 Homme Enseignement superieur y compris technique superieur 1700.84366 Retraite Cadre 2 Oui Ni croyance ni appartenance NA NA Non Non Oui Non Non Non Non 3.0
27 31 Femme Enseignement technique ou professionnel long 6662.83748 Exerce une profession Ouvrier qualifie 1 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Non Non 1.0
28 35 Homme 1er cycle 3359.46898 Exerce une profession Ouvrier specialise 6 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Oui Non Non Non Non 1.0
29 35 Homme Enseignement technique ou professionnel court 8536.11006 Exerce une profession Ouvrier qualifie 2 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Non Non 4.0
30 30 Homme Enseignement technique ou professionnel court 10620.52591 Exerce une profession Ouvrier qualifie 1 Oui Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Oui Oui Oui Oui Oui 3.0
31 54 Homme Enseignement technique ou professionnel court 5264.29531 Exerce une profession Employe 2 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Non Non 0.0
32 29 Homme Enseignement technique ou professionnel court 14161.75971 Exerce une profession Autre 2 Oui Appartenance sans pratique Moins important que le reste Satisfaction Oui Non Non Oui Oui Oui Non 1.0
33 49 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 1339.61963 Exerce une profession NA 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Oui Non Oui Non Non 1.0
34 59 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 9243.91526 Exerce une profession NA 9 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Oui Non Oui Non Non Non 2.0
35 41 Femme Enseignement technique ou professionnel court 4512.29590 Chomeur Ouvrier qualifie 2 Non Pratiquant occasionnel NA NA Non Non Non Oui Oui Oui Oui 2.0
36 41 Femme 1er cycle 7871.64520 Exerce une profession Employe 3 Oui Rejet Moins important que le reste Insatisfaction Non Non Non Non Non Oui Non 4.0
37 53 Homme Enseignement technique ou professionnel court 1356.96207 Exerce une profession Ouvrier qualifie 0 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Oui Non Oui 1.0
38 19 Femme NA 7626.33003 Etudiant, eleve NA 1 Non Appartenance sans pratique NA NA Non Non Non Non Non Oui Oui 2.0
39 77 Femme Derniere annee d’etudes primaires 1630.27458 Retraite Employe 3 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 3.0
40 56 Homme Enseignement superieur y compris technique superieur 2196.24853 Exerce une profession Cadre 1 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Non Non 3.0
41 54 Femme Derniere annee d’etudes primaires 5605.98462 Chomeur Employe 9 Non Appartenance sans pratique NA NA Non Non Oui Non Non Oui Non 4.0
42 35 Homme Enseignement technique ou professionnel court 8841.29604 Exerce une profession Ouvrier qualifie 8 Non Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Non Non Non Non Non 3.0
43 40 Homme Enseignement superieur y compris technique superieur 9113.53784 Exerce une profession Cadre 3 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Non Oui 0.4
44 62 Femme NA 2267.59121 Retraite Cadre 2 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Oui 2.0
45 68 Femme Derniere annee d’etudes primaires 7706.29436 Retraite NA 4 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 2.0
46 77 Homme Derniere annee d’etudes primaires 2446.51113 Retraite Ouvrier qualifie 0 Non NSP ou NVPR NA NA Non Non Non Non Oui Non Non 2.0
47 39 Femme Enseignement technique ou professionnel court 8118.26387 Exerce une profession Ouvrier specialise 12 Non Pratiquant occasionnel Peu important Equilibre Non Non Oui Oui Non Non Non 3.0
48 57 Femme 1er cycle 10751.50367 Au foyer NA 6 Oui Pratiquant regulier NA NA Non Non Non Oui Non Non Non 3.0
49 43 Femme Enseignement superieur y compris technique superieur 831.85990 Exerce une profession Employe 2 Oui Pratiquant occasionnel Aussi important que le reste Equilibre Non Non Non Non Non Non Non 2.0
50 34 Femme Enseignement superieur y compris technique superieur 6591.64398 Exerce une profession Cadre 2 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Non Non 0.0
51 60 Homme Derniere annee d’etudes primaires 1936.88263 Retraite Profession intermediaire 2 Non Appartenance sans pratique NA NA Non Non Non Non Oui Oui Non 3.0
52 41 Femme Enseignement technique ou professionnel court 834.38451 Chomeur Employe 1 Non Ni croyance ni appartenance NA NA Non Non Non Oui Non Non Non 3.0
53 54 Homme Enseignement technique ou professionnel court 3432.52858 Exerce une profession Autre 3 Oui Pratiquant regulier Le plus important Satisfaction Non Non Non Non Non Non Non 2.0
54 23 Femme Enseignement superieur y compris technique superieur 11354.89319 Au foyer NA 1 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 3.0
55 26 Homme Enseignement superieur y compris technique superieur 9292.97620 Exerce une profession Technicien 1 Oui Rejet Peu important Insatisfaction Non Non Non Non Non Oui Oui 1.4
56 23 Femme Enseignement technique ou professionnel long 6344.12272 Exerce une profession Ouvrier specialise 1 Oui Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Oui Non Non Non 2.0
57 74 Femme Derniere annee d’etudes primaires 4899.94038 Retraite NA 2 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 3.0
58 60 Femme Enseignement superieur y compris technique superieur 4766.86520 Au foyer Cadre 3 Non Pratiquant regulier NA NA Non Non Non Non Oui Oui Oui 2.0
59 23 Homme Enseignement technique ou professionnel long 3462.81206 Chomeur Employe 4 Oui Appartenance sans pratique NA NA Non Non Non Non Non Oui Non 4.0
60 57 Femme Enseignement superieur y compris technique superieur 23732.48529 Exerce une profession NA 1 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Non Non Non 0.0
61 55 Femme Enseignement technique ou professionnel court 833.84284 Chomeur Employe 1 Non Appartenance sans pratique NA NA Non Non Non Oui Oui Non Oui 3.0
62 71 Homme Derniere annee d’etudes primaires 8529.44029 Retire des affaires NA 5 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Oui 3.0
63 39 Homme Enseignement technique ou professionnel court 3190.36798 Exerce une profession Ouvrier qualifie 0 Oui Rejet Aussi important que le reste Satisfaction Non Non Non Non Oui Non Non 2.0
64 56 Homme Derniere annee d’etudes primaires 2423.10519 Exerce une profession NA 8 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Oui Non Non 2.0
65 54 Homme 1er cycle 5945.99294 Exerce une profession Ouvrier qualifie 2 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Non Non 4.0
66 27 Femme Derniere annee d’etudes primaires 14991.86521 Exerce une profession Employe 1 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Non Oui Oui 2.0
67 40 Homme 1er cycle 2062.11243 Exerce une profession Ouvrier qualifie 2 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Oui Non Non 4.0
68 42 Homme Enseignement technique ou professionnel court 5702.06235 Exerce une profession Ouvrier qualifie 3 Non Ni croyance ni appartenance Aussi important que le reste Insatisfaction Non Non Oui Non Oui Non Non 3.0
69 44 Femme 1er cycle 20604.26420 Exerce une profession Employe 8 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Oui Non Oui Oui Oui 0.4
70 41 Femme 2eme cycle 2634.48613 Au foyer NA 5 Ne sait pas Pratiquant regulier NA NA Non Non Non Oui Non Oui Non 2.0
71 30 Homme Enseignement technique ou professionnel long 13544.62124 Exerce une profession Ouvrier qualifie 1 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Non Oui Non 1.4
72 48 Homme Enseignement technique ou professionnel court 4748.77279 Exerce une profession Ouvrier specialise 2 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Oui Non Non 1.0
73 59 Femme Enseignement technique ou professionnel court 2348.37809 Retraite Employe 3 Oui Appartenance sans pratique NA NA Non Non Non Oui Oui Non Oui 3.0
74 46 Femme Enseignement technique ou professionnel court 3718.83896 Exerce une profession Employe 1 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 2.0
75 33 Femme Enseignement technique ou professionnel court 3850.60898 Exerce une profession Employe 4 Oui Ni croyance ni appartenance Peu important Insatisfaction Non Non Non Oui Oui Oui Non 3.0
76 70 Femme 1er cycle 6571.58950 Autre inactif Ouvrier qualifie 5 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 2.0
77 67 Homme 2eme cycle 3238.32040 Retraite Ouvrier qualifie 2 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 3.0
78 75 Femme Derniere annee d’etudes primaires 17333.25440 Retire des affaires NA 2 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 1.0
79 22 Femme Enseignement technique ou professionnel court 6168.50167 Exerce une profession Employe 3 Oui Rejet Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 2.0
80 51 Femme Enseignement superieur y compris technique superieur 7357.92915 Exerce une profession NA 4 Non Pratiquant regulier Aussi important que le reste Satisfaction Non Oui Non Non Oui Oui Non 0.0
81 41 Femme Enseignement technique ou professionnel long 3909.55864 Exerce une profession Employe 6 Non Ni croyance ni appartenance Aussi important que le reste Equilibre Non Oui Non Oui Non Oui Non 5.0
82 53 Femme Derniere annee d’etudes primaires 1514.06192 Autre inactif Employe 5 Non NSP ou NVPR NA NA Non Non Non Oui Oui Non Non 2.0
83 70 Femme Derniere annee d’etudes primaires 2916.92540 Retraite Ouvrier qualifie 6 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 3.0
84 79 Homme Enseignement superieur y compris technique superieur 3156.08224 Retraite Cadre 2 Oui Pratiquant occasionnel NA NA Non Non Non Non Oui Non Oui 4.0
85 31 Homme Enseignement superieur y compris technique superieur 12404.57949 Exerce une profession NA 3 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 1.0
86 34 Femme Enseignement superieur y compris technique superieur 2388.01142 Exerce une profession Cadre 0 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Non Oui Non 0.4
87 72 Homme 1er cycle 6590.63843 Retraite Ouvrier qualifie 7 Oui Pratiquant occasionnel NA NA Non Non Non Non Oui Non Non 4.0
88 59 Homme 2eme cycle 2590.60932 Exerce une profession Cadre 2 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Oui Non Oui Non Non 1.0
89 63 Homme 2eme cycle 2786.29662 Retraite Profession intermediaire 1 Non Pratiquant occasionnel NA NA Non Non Non Oui Oui Non Non 4.0
90 77 Homme Enseignement superieur y compris technique superieur 7457.67187 Retraite Cadre 4 Oui Pratiquant regulier NA NA Non Non Non Non Oui Non Non 3.0
91 48 Homme Enseignement superieur y compris technique superieur 11076.90257 Exerce une profession Cadre 1 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Non Oui Non 0.6
92 25 Femme Enseignement superieur y compris technique superieur 2841.47129 Exerce une profession Cadre 1 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Non Oui Oui 2.0
93 62 Homme Enseignement technique ou professionnel court 2422.14819 Retraite Ouvrier qualifie 10 Non Appartenance sans pratique NA NA Non Non Non Oui Oui Non Non 4.0
94 23 Femme NA 4454.33180 Etudiant, eleve NA 0 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Oui Oui 0.0
95 66 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 5581.58420 Au foyer NA 13 Oui Pratiquant occasionnel NA NA Non Non Non Oui Oui Non Non 6.0
96 90 Femme Derniere annee d’etudes primaires 5875.03995 Au foyer Employe 7 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 4.0
97 43 Homme Enseignement technique ou professionnel court 2064.08485 Exerce une profession Ouvrier qualifie 6 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Oui Non Oui Oui Non 2.0
98 32 Homme 2eme cycle 827.70358 Exerce une profession Employe 1 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Oui Non Oui Oui Oui 4.0
99 54 Femme 1er cycle 13405.10469 Au foyer Ouvrier specialise 4 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 6.0
100 19 Femme NA 2186.54041 Exerce une profession Employe 0 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Non 10.0
101 61 Femme Enseignement technique ou professionnel court 22962.35960 Retraite Cadre 1 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 4.0
102 57 Homme Derniere annee d’etudes primaires 11268.55561 Exerce une profession NA 0 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Oui Non Oui 1.0
103 54 Femme Enseignement superieur y compris technique superieur 2032.21525 Exerce une profession Cadre 2 Oui Pratiquant occasionnel Le plus important Insatisfaction Non Non Non Non Oui Oui Non 2.9
104 31 Homme Derniere annee d’etudes primaires 3173.02478 Exerce une profession Ouvrier specialise 8 Non Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Non Non Oui Oui Non 3.0
105 33 Homme Enseignement technique ou professionnel court 10483.54536 Exerce une profession Profession intermediaire 1 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Oui Oui Oui 0.0
106 86 Femme Derniere annee d’etudes primaires 2395.82957 Au foyer Ouvrier specialise 2 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 5.0
107 84 Femme Derniere annee d’etudes primaires 12265.60802 Retire des affaires NA 3 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Non Oui 4.0
108 74 Femme Derniere annee d’etudes primaires 5844.38619 Retraite Employe 1 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 2.0
109 49 Femme Enseignement superieur y compris technique superieur 1114.64958 Exerce une profession Cadre 1 Non Pratiquant regulier Moins important que le reste Insatisfaction Non Oui Non Oui Non Oui Oui 0.9
110 47 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 3172.98165 Exerce une profession Ouvrier qualifie 5 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Oui Non Oui 3.0
111 25 Homme NA 4631.18837 Etudiant, eleve NA 2 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Oui Non 0.6
112 52 Homme Derniere annee d’etudes primaires 7194.16793 Exerce une profession Employe 1 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Oui Non Oui 0.0
113 71 Homme Enseignement superieur y compris technique superieur 3437.08850 Retraite Cadre 1 Oui Appartenance sans pratique NA NA Non Non Non Non Non Oui Non 2.0
114 56 Homme Enseignement technique ou professionnel long 1131.59356 Exerce une profession Technicien 2 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Non Non 2.0
115 58 Femme Enseignement superieur y compris technique superieur 8463.95303 Retraite Profession intermediaire 0 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Oui Oui 1.0
116 66 Homme Enseignement technique ou professionnel court 15556.25846 Retire des affaires NA 4 Non Pratiquant regulier NA NA Non Non Oui Oui Non Non Non 7.0
117 70 Homme 1er cycle 2662.08516 Retraite Employe 4 Oui Pratiquant occasionnel NA NA Non Non Non Non Oui Non Non 2.0
118 51 Femme 2eme cycle 8147.55346 Au foyer Profession intermediaire 0 Non Pratiquant occasionnel NA NA Non Non Oui Oui Non Non Non 2.0
119 54 Homme 1er cycle 1726.75003 Exerce une profession Autre 3 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Non Non Non 1.0
120 73 Homme Derniere annee d’etudes primaires 4921.91931 Retraite Ouvrier qualifie 1 Oui Appartenance sans pratique NA NA Non Non Oui Non Oui Non Non 0.0
121 35 Femme Enseignement superieur y compris technique superieur 284.16068 Exerce une profession Profession intermediaire 4 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Oui Oui Oui 0.3
122 64 Femme 2eme cycle 3224.73134 Retraite Employe 3 Oui Appartenance sans pratique NA NA Non Non Non Non Non Oui Non 4.0
123 51 Femme 2eme cycle 1483.76383 Exerce une profession Profession intermediaire 1 Non Rejet Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 5.0
124 68 Homme Enseignement technique ou professionnel court 6341.86469 Retire des affaires NA 2 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 3.0
125 42 Femme 2eme cycle 9516.12798 Au foyer Employe 3 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Oui Oui 3.0
126 49 Femme Enseignement technique ou professionnel court 7174.80941 Exerce une profession Ouvrier specialise 5 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Non Non Non 6.0
127 55 Homme Derniere annee d’etudes primaires 2954.27411 Retraite Employe 3 Non Pratiquant occasionnel NA NA Non Non Oui Non Non Non Non 0.0
128 49 Femme Enseignement superieur y compris technique superieur 8819.37612 Exerce une profession Cadre 0 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Non Oui Non 1.0
129 60 Femme Enseignement technique ou professionnel court 1117.19960 Retraite Employe 6 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 2.0
130 71 Homme Derniere annee d’etudes primaires 6721.40093 Retraite NA 5 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 1.0
131 75 Femme Derniere annee d’etudes primaires 7975.21857 Retraite Employe 3 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 5.0
132 36 Homme Enseignement superieur y compris technique superieur 9081.31588 Exerce une profession Cadre 2 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Non Oui Oui 1.0
133 78 Femme Derniere annee d’etudes primaires 10783.41051 Retire des affaires NA 3 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 0.0
134 19 Femme NA 7444.42715 Etudiant, eleve NA 1 Non Ni croyance ni appartenance NA NA Non Non Non Non Oui Oui Non 0.0
135 23 Femme Enseignement superieur y compris technique superieur 5276.45519 Chomeur Employe 2 Oui Ni croyance ni appartenance NA NA Non Oui Non Non Non Non Non 3.0
136 81 Homme 2eme cycle 7736.58228 Retire des affaires NA 1 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Oui 3.0
137 41 Homme Enseignement superieur y compris technique superieur 8338.04877 Exerce une profession NA 1 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 1.0
138 58 Homme Enseignement technique ou professionnel court 7103.50084 Exerce une profession Profession intermediaire 2 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Non Non 3.0
139 37 Homme Enseignement technique ou professionnel court 608.57053 Exerce une profession Ouvrier qualifie 1 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Oui Non Oui Non Oui 3.0
140 49 Homme Enseignement technique ou professionnel court 660.95776 Exerce une profession Technicien 5 Non Rejet Moins important que le reste Satisfaction Non Non Non Non Oui Oui Non 1.0
141 55 Homme 1er cycle 313.64342 Exerce une profession Ouvrier qualifie 6 Non Appartenance sans pratique Aussi important que le reste Insatisfaction Non Non Non Oui Oui Non Non 4.0
142 51 Homme 1er cycle 9668.31478 Exerce une profession Ouvrier qualifie 4 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Oui Non Oui 3.0
143 58 Homme Enseignement superieur y compris technique superieur 8222.27349 Exerce une profession Autre 7 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Oui Oui Non 2.0
144 29 Femme 1er cycle 1847.10729 Au foyer Ouvrier specialise 6 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 2.0
145 47 Homme Enseignement superieur y compris technique superieur 4264.91744 Exerce une profession Profession intermediaire 4 Non Ni croyance ni appartenance Peu important Equilibre Non Non Non Non Non Oui Oui 3.0
146 78 Homme Derniere annee d’etudes primaires 5684.05668 Retraite Ouvrier specialise 4 Oui Pratiquant occasionnel NA NA Non Non Non Non Oui Non Non 5.0
147 31 Homme Enseignement superieur y compris technique superieur 4157.13409 Exerce une profession Technicien 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Oui Non Non Oui Non Oui Oui 2.0
148 55 Femme Enseignement superieur y compris technique superieur 2346.81267 Au foyer Autre 2 Non Appartenance sans pratique NA NA Non Non Non Oui Oui Non Non 2.0
149 42 Femme Enseignement technique ou professionnel court 615.96304 Exerce une profession Employe 3 Oui Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Oui Non Non Oui 2.0
150 35 Femme 2eme cycle 7704.76840 Exerce une profession Employe 3 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Non Non Non 1.0
151 50 Homme Derniere annee d’etudes primaires 566.58165 Exerce une profession Employe 2 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 2.0
152 78 Femme Derniere annee d’etudes primaires 578.00909 Retraite Employe 3 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 3.0
153 56 Femme Enseignement technique ou professionnel long 8547.32348 Exerce une profession NA 1 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Oui Non Non 1.0
154 40 Femme Enseignement technique ou professionnel court 6123.69218 Exerce une profession Autre 3 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Oui Oui Non 2.0
155 35 Femme 1er cycle 3580.08617 Au foyer Employe 3 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 5.0
156 46 Homme N’a jamais fait d’etudes 1087.88725 Autre inactif NA 7 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 5.0
157 50 Femme Enseignement technique ou professionnel court 3963.18408 Exerce une profession Employe 7 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Non Non 0.0
158 69 Homme Enseignement technique ou professionnel long 7310.11222 Retraite Profession intermediaire 5 Non Appartenance sans pratique NA NA Non Non Oui Non Oui Oui Non 2.0
159 73 Homme 2eme cycle 2063.17748 Retraite Employe 5 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 0.0
160 32 Homme Enseignement technique ou professionnel court 7514.76413 Exerce une profession Ouvrier qualifie 9 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Oui Oui Oui Non Non 2.0
161 38 Femme 2eme cycle 1446.39665 Exerce une profession Cadre 5 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Oui Non 4.0
162 18 Homme NA 4982.96438 Etudiant, eleve NA 2 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Oui 3.0
163 43 Femme 2eme cycle 8386.74313 Exerce une profession Cadre 2 Oui Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Oui Oui Oui Non 0.3
164 62 Homme Enseignement technique ou professionnel long 1598.41673 Retraite Profession intermediaire 1 Non Rejet NA NA Non Non Oui Non Non Non Non 0.0
165 35 Femme 1er cycle 1753.67646 Exerce une profession Employe 5 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Non Oui 0.0
166 28 Homme Enseignement technique ou professionnel long 8999.28848 Exerce une profession Employe 1 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Non Non Oui 1.7
167 51 Homme Enseignement technique ou professionnel long 2246.76322 Exerce une profession Ouvrier qualifie 7 Non Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Non Non Non Non 3.0
168 65 Femme 2eme cycle 405.10883 Au foyer NA 3 Oui Appartenance sans pratique NA NA Non Non Non Oui Oui Oui Oui 3.0
169 47 Femme 2eme cycle 2295.74905 Exerce une profession Employe 11 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 2.0
170 66 Femme Derniere annee d’etudes primaires 1909.16143 Retraite Employe 1 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 8.0
171 48 Homme 2eme cycle 6299.06769 Exerce une profession Employe 2 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Non Oui Oui 1.4
172 27 Femme Enseignement superieur y compris technique superieur 3078.10631 Exerce une profession Employe 3 Non Pratiquant regulier Aussi important que le reste Satisfaction Non Non Non Non Oui Oui Oui 0.3
173 71 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 6468.77209 Retire des affaires NA 3 Oui Appartenance sans pratique NA NA Non Non Non Oui Oui Non Non 7.0
174 38 Femme Enseignement superieur y compris technique superieur 5267.87477 Exerce une profession Employe 1 Oui Rejet Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 0.4
175 61 Femme Derniere annee d’etudes primaires 603.27698 Retraite Employe 2 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 4.0
176 39 Femme Enseignement superieur y compris technique superieur 1645.86876 Exerce une profession Cadre 3 Non Rejet Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 0.1
177 69 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 12745.01230 Retire des affaires NA 14 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Oui 2.0
178 79 Homme Derniere annee d’etudes primaires 8196.61223 Retraite Ouvrier qualifie 2 Oui Rejet NA NA Non Non Non Non Oui Non Non 6.0
179 57 Homme Derniere annee d’etudes primaires 7697.18733 Exerce une profession Ouvrier specialise 2 Oui Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Non Oui Non Non 3.0
180 64 Femme Enseignement superieur y compris technique superieur 5794.55269 Retraite Cadre 3 Non Appartenance sans pratique NA NA Non Non Non Oui Non Oui Oui 0.7
181 59 Homme Enseignement technique ou professionnel court 388.10276 Autre inactif Ouvrier qualifie 3 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 6.0
182 47 Femme Enseignement superieur y compris technique superieur 914.68026 Au foyer Ouvrier qualifie 5 Non Ni croyance ni appartenance NA NA Non Non Non Oui Oui Non Non 0.0
183 24 Femme Enseignement superieur y compris technique superieur 15044.27884 Exerce une profession Employe 2 Oui Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Oui Oui Oui Oui 4.0
184 54 Homme Enseignement technique ou professionnel court 6648.04006 Exerce une profession NA 6 Oui Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Non Oui Non Non 1.0
185 50 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 7739.15153 Exerce une profession Ouvrier qualifie 18 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Non Non 6.0
186 32 Femme 2eme cycle 2228.64869 Au foyer Autre 1 Non Pratiquant regulier NA NA Non Non Non Oui Oui Non Non 4.0
187 60 Femme Enseignement technique ou professionnel court 7118.46585 Retraite Cadre 4 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Oui Non 1.0
188 57 Femme Enseignement technique ou professionnel court 1419.54106 Exerce une profession Employe 0 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Non Non Non 1.0
189 50 Femme Derniere annee d’etudes primaires 7834.43197 Autre inactif Employe 11 Oui Ni croyance ni appartenance NA NA Non Non Non Oui Oui Non Non 4.0
190 23 Femme 2eme cycle 12923.54577 Chomeur Employe 3 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Oui Oui 9.0
191 48 Homme Enseignement technique ou professionnel court 2324.48127 Exerce une profession Profession intermediaire 3 Oui Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Non Oui Non Non 3.0
192 49 Homme Derniere annee d’etudes primaires 6626.08984 Exerce une profession Ouvrier qualifie 3 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Oui Oui Non Non Non 3.0
193 70 Femme 1er cycle 16784.05908 Retire des affaires NA 0 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 2.0
194 27 Homme Enseignement superieur y compris technique superieur 6242.18862 Chomeur Cadre 0 Non Appartenance sans pratique NA NA Non Non Non Non Oui Oui Oui 1.0
195 52 Homme 2eme cycle 958.43064 Exerce une profession Ouvrier qualifie 8 Oui Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Non Oui Non Non 4.0
196 19 Femme NA 20766.92539 Etudiant, eleve NA 1 Non Appartenance sans pratique NA NA Non Non Non Non Non Oui Non 2.0
197 54 Homme Enseignement superieur y compris technique superieur 5954.67384 Exerce une profession Cadre 2 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Non Oui Oui 2.0
198 45 Femme Enseignement superieur y compris technique superieur 637.94885 Chomeur Cadre 2 Oui Pratiquant regulier NA NA Non Non Non Oui Oui Oui Oui 0.6
199 64 Homme Enseignement technique ou professionnel court 2525.46984 Retraite Cadre 1 Oui Pratiquant occasionnel NA NA Non Non Oui Non Oui Oui Non 2.0
200 71 Femme Enseignement technique ou professionnel long 8540.51444 Autre inactif Employe 2 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 2.0
201 34 Femme Enseignement technique ou professionnel long 8601.02300 Exerce une profession Employe 7 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Non 2.0
202 38 Homme Enseignement superieur y compris technique superieur 6781.55643 Exerce une profession Cadre 3 Non Ni croyance ni appartenance Moins important que le reste Insatisfaction Non Non Non Non Oui Oui Non 4.0
203 27 Femme Enseignement technique ou professionnel long 6516.50773 Exerce une profession Employe 3 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Oui Oui Non 0.0
204 19 Homme NA 6339.69459 Etudiant, eleve NA 1 Non Appartenance sans pratique NA NA Non Non Non Oui Non Oui Oui 1.0
205 22 Femme Enseignement technique ou professionnel long 6529.89704 Exerce une profession Employe 1 Non Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Oui Non Oui Oui 3.0
206 66 Homme 2eme cycle 5802.14765 Retraite Profession intermediaire 6 Oui Appartenance sans pratique NA NA Non Non Oui Non Non Non Non 2.0
207 47 Femme Derniere annee d’etudes primaires 2554.52735 Exerce une profession Ouvrier specialise 6 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Non Non Non 5.0
208 47 Femme 2eme cycle 5100.79858 Chomeur Employe 2 Non Ni croyance ni appartenance NA NA Non Non Non Oui Oui Oui Oui 1.1
209 48 Homme 2eme cycle 7323.01540 Retraite Employe 3 Oui Pratiquant regulier NA NA Non Non Non Non Non Oui Oui 1.0
210 63 Femme Derniere annee d’etudes primaires 13644.79087 Au foyer Employe 7 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 4.0
211 36 Femme Enseignement technique ou professionnel long 3782.09995 Exerce une profession Employe 1 Oui NSP ou NVPR Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 2.0
212 68 Femme Derniere annee d’etudes primaires 2644.51957 Retraite Employe 1 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 2.0
213 36 Femme 2eme cycle 2396.54667 Chomeur Employe 0 Non Appartenance sans pratique NA NA Non Non Non Non Non Oui Non 4.0
214 69 Femme Derniere annee d’etudes primaires 1966.06490 Autre inactif Employe 4 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 0.0
215 18 Homme NA 4631.18837 Etudiant, eleve NA 2 Oui Ni croyance ni appartenance NA NA Non Non Non Oui Non Oui Oui 2.0
216 29 Femme 1er cycle 16582.83445 Chomeur Employe 7 Non Rejet NA NA Non Non Non Oui Non Non Non 2.0
217 22 Femme NA 8839.36792 Etudiant, eleve NA 2 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 0.0
218 74 Femme Derniere annee d’etudes primaires 5780.19971 Retraite Employe 3 Non Appartenance sans pratique NA NA Non Non Oui Non Non Non Non 2.0
219 32 Femme Enseignement technique ou professionnel court 8601.02300 Exerce une profession Employe 1 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Oui Oui 0.0
220 72 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 3680.22755 Retire des affaires NA 0 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 0.0
221 26 Homme 2eme cycle 9319.76072 Exerce une profession Ouvrier qualifie 2 Oui Pratiquant occasionnel Le plus important Equilibre Non Non Non Oui Oui Non Non 1.0
222 77 Homme Enseignement superieur y compris technique superieur 909.57573 Retraite Profession intermediaire 2 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 0.0
223 51 Femme Derniere annee d’etudes primaires 7924.95125 Exerce une profession NA 1 Non Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Oui Non Non Non 3.0
224 56 Femme 1er cycle 1113.08174 Exerce une profession Employe 5 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Non Non Non 2.0
225 52 Femme Enseignement technique ou professionnel court 1649.34744 Au foyer Ouvrier qualifie 1 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 3.0
226 71 Femme N’a jamais fait d’etudes 1824.26403 Retraite Ouvrier specialise 15 Non Rejet NA NA Non Non Non Oui Non Non Non 3.0
227 78 Femme Derniere annee d’etudes primaires 1583.23777 Autre inactif NA 3 Oui Pratiquant regulier NA NA Non Non Non Oui Non Non Non 3.0
228 29 Homme Enseignement technique ou professionnel court 5735.28923 Exerce une profession Ouvrier specialise 1 Non Ni croyance ni appartenance Le plus important Equilibre Non Non Oui Non Oui Non Non 0.0
229 43 Femme Derniere annee d’etudes primaires 1199.49021 Exerce une profession Employe 5 Non Rejet Moins important que le reste Equilibre Non Non Non Oui Oui Oui Non 0.3
230 63 Femme Enseignement technique ou professionnel court 6688.77708 Retraite Employe 5 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Oui Non 2.0
231 20 Femme Enseignement technique ou professionnel court 8463.64000 Chomeur Employe 2 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Oui Non NA
232 43 Femme Enseignement superieur y compris technique superieur 1544.16371 Exerce une profession Technicien 2 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 0.0
233 41 Femme 2eme cycle 1962.92019 Exerce une profession Employe 1 Oui Pratiquant regulier Moins important que le reste Equilibre Non Non Non Non Oui Non Non 0.0
234 55 Homme Enseignement technique ou professionnel court 663.50864 Retraite Employe 2 Non Rejet NA NA Non Non Oui Oui Non Non Non 1.4
235 92 Homme N’a jamais fait d’etudes 827.45367 Retraite Ouvrier specialise 0 Ne sait pas Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 3.0
236 78 Femme 1er cycle 2968.15453 Retraite Ouvrier qualifie 1 Oui Rejet NA NA Non Non Non Oui Non Non Non 10.0
237 31 Femme Enseignement technique ou professionnel court 953.63157 Au foyer NA 10 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 3.0
238 49 Femme Enseignement technique ou professionnel court 511.93962 Autre inactif Employe 5 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 4.0
239 30 Femme Enseignement technique ou professionnel long 6165.34358 Exerce une profession Profession intermediaire 0 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Oui Non 2.0
240 58 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 2446.32898 Au foyer Ouvrier specialise 7 Non Pratiquant occasionnel NA NA Non Non Non Oui Oui Non Non 2.0
241 37 Homme Enseignement technique ou professionnel court 10216.94872 Exerce une profession Autre 5 Non Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Oui Non Non Non Non 2.0
242 66 Homme Enseignement superieur y compris technique superieur 10886.75741 Retraite Cadre 2 Non Rejet NA NA Non Non Non Non Oui Oui Non 3.0
243 28 Femme NA 9322.52307 Etudiant, eleve Autre 1 Non Appartenance sans pratique NA NA Non Non Non Non Non Oui Oui 2.0
244 53 Homme Enseignement superieur y compris technique superieur 1812.90182 Exerce une profession Cadre 1 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Oui Oui Oui 0.1
245 70 Homme Enseignement technique ou professionnel court 10132.22271 Retraite Ouvrier qualifie 3 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Oui 0.0
246 72 Homme Derniere annee d’etudes primaires 4433.48174 Retire des affaires NA 5 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 2.0
247 72 Homme Enseignement technique ou professionnel court 4865.92453 Retraite Profession intermediaire 0 Non Pratiquant occasionnel NA NA Non Non Non Non Oui Non Non 3.0
248 69 Femme Derniere annee d’etudes primaires 4974.33148 Retraite Employe 0 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 5.0
249 56 Femme Enseignement superieur y compris technique superieur 3170.59831 Retraite Profession intermediaire 4 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 0.0
250 56 Femme 2eme cycle 858.28121 Au foyer Profession intermediaire 2 Oui Ni croyance ni appartenance NA NA Non Non Non Oui Oui Oui Non 3.0
251 40 Femme 1er cycle 13603.21874 Exerce une profession Employe 2 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Oui Oui Non 1.0
252 39 Homme Enseignement superieur y compris technique superieur 1043.59583 Exerce une profession Cadre 4 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 1.0
253 35 Femme Enseignement superieur y compris technique superieur 2224.88512 Exerce une profession Profession intermediaire 3 Oui Ni croyance ni appartenance Le plus important Insatisfaction Non Non Non Oui Oui Non Non 2.0
254 43 Homme Enseignement technique ou professionnel court 3732.58313 Exerce une profession Ouvrier qualifie 5 Non Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Non Oui Oui Oui Non 2.0
255 66 Homme Enseignement technique ou professionnel court 2330.03915 Retraite Ouvrier qualifie 0 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 0.0
256 19 Femme NA 3298.37878 Etudiant, eleve NA 3 Oui Pratiquant regulier NA NA Non Non Non Oui Non Non Non 1.0
257 19 Femme NA 10397.02130 Etudiant, eleve NA 1 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Oui Non 1.1
258 31 Homme Enseignement superieur y compris technique superieur 9865.73934 Exerce une profession Cadre 2 Oui Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Oui Non Oui Oui Oui 1.0
259 42 Femme Enseignement superieur y compris technique superieur 3258.31269 Exerce une profession Employe 2 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Non Oui Non 2.0
260 72 Homme Derniere annee d’etudes primaires 2614.50724 Retraite Technicien 4 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 3.0
261 47 Homme Enseignement technique ou professionnel court 6329.20973 Exerce une profession Ouvrier qualifie 2 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Oui Non Oui Oui Oui 2.0
262 21 Homme Enseignement technique ou professionnel court 10519.60681 Exerce une profession Ouvrier qualifie 2 Non Rejet Aussi important que le reste Satisfaction Non Non Non Non Non Oui Non 2.0
263 43 Femme 1er cycle 4419.32999 Chomeur Employe 5 Non Appartenance sans pratique NA NA Non Non Non Oui Oui Oui Oui 1.0
264 44 Femme Enseignement superieur y compris technique superieur 3912.49163 Exerce une profession Employe 4 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Non Oui Oui 0.0
265 57 Homme Derniere annee d’etudes primaires 1960.08349 Autre inactif Ouvrier qualifie 5 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 4.0
266 83 Femme Derniere annee d’etudes primaires 92.68033 Au foyer Employe 1 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 1.0
267 47 Femme 1er cycle 5348.60718 Chomeur Employe 4 Oui Appartenance sans pratique NA NA Non Non Oui Oui Oui Non Non 3.0
268 34 Homme Enseignement superieur y compris technique superieur 2377.48515 Exerce une profession Cadre 1 Non Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Non Oui Oui Oui 1.0
269 74 Homme Derniere annee d’etudes primaires 1917.81751 Retraite Ouvrier qualifie 1 Oui Pratiquant occasionnel NA NA Non Oui Non Non Oui Non Non 6.0
270 96 Femme Derniere annee d’etudes primaires 9993.02007 Retraite NA 1 Oui Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 6.0
271 52 Femme Enseignement superieur y compris technique superieur 5616.38436 Exerce une profession Profession intermediaire 1 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 0.3
272 49 Homme Enseignement superieur y compris technique superieur 1970.19401 Exerce une profession NA 3 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Oui Oui Oui 1.0
273 41 Femme 2eme cycle 1807.99246 Exerce une profession Employe 6 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Non Oui Oui 0.0
274 59 Femme Enseignement technique ou professionnel court 2128.04704 Chomeur Autre 3 Oui Pratiquant occasionnel NA NA Non Non Non Oui Oui Non Oui 3.0
275 81 Femme Enseignement technique ou professionnel court 2968.15453 Retraite Employe 0 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 3.0
276 36 Femme Enseignement technique ou professionnel court 1611.80358 Exerce une profession Ouvrier specialise 2 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Non Non Non 1.0
277 36 Homme Enseignement technique ou professionnel court 2170.15344 Exerce une profession Ouvrier qualifie 1 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Oui Non Non Non Oui 1.0
278 38 Homme Enseignement technique ou professionnel court 10120.05933 Exerce une profession Ouvrier qualifie 8 Non Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Non Non Oui Non 5.0
279 46 Femme Enseignement superieur y compris technique superieur 4054.42253 Exerce une profession Technicien 1 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 1.4
280 54 Homme Enseignement technique ou professionnel court 8970.64438 Exerce une profession Profession intermediaire 4 Non Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Non Oui Non Non 0.0
281 63 Homme 1er cycle 1991.46873 Exerce une profession NA 1 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Oui Oui Oui Oui Non 3.0
282 26 Homme Enseignement superieur y compris technique superieur 8150.71674 Exerce une profession Autre 2 Non Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Oui Oui Oui Oui Oui 2.9
283 57 Homme N’a jamais fait d’etudes 10164.79164 Retire des affaires NA 3 Non Ni croyance ni appartenance NA NA Non Non Non Oui Non Non Non 1.0
284 84 Femme Derniere annee d’etudes primaires 4468.97627 Retraite Employe 0 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 3.0
285 62 Femme Enseignement technique ou professionnel court 2220.78754 Retraite Employe 0 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 4.0
286 66 Femme Derniere annee d’etudes primaires 1184.43725 Retraite Ouvrier specialise 6 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 3.0
287 35 Femme Enseignement superieur y compris technique superieur 2543.56180 Etudiant, eleve Cadre 1 Non Appartenance sans pratique NA NA Non Non Non Oui Non Oui Non 1.0
288 72 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 7111.84326 Autre inactif Autre 3 Oui Rejet NA NA Non Non Non Non Non Non Non 12.0
289 69 Femme 2eme cycle 10180.34321 Retraite Employe 2 Oui Ni croyance ni appartenance NA NA Non Non Non Non Non Oui Non 0.0
290 66 Homme Derniere annee d’etudes primaires 1427.06355 Retraite Ouvrier qualifie 4 Oui Appartenance sans pratique NA NA Non Non Oui Non Oui Non Non 4.0
291 27 Femme Enseignement superieur y compris technique superieur 13480.67822 Exerce une profession Employe 2 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 1.0
292 40 Homme Enseignement superieur y compris technique superieur 2415.95301 Chomeur Ouvrier qualifie 2 Oui Appartenance sans pratique NA NA Non Non Non Non Non Oui Oui 4.0
293 30 Femme Enseignement superieur y compris technique superieur 9819.23024 Exerce une profession Cadre 1 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Non Non Oui 2.0
294 48 Femme 2eme cycle 4270.25296 Exerce une profession Profession intermediaire 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Oui 0.0
295 56 Homme Enseignement technique ou professionnel court 3642.84502 Autre inactif Ouvrier qualifie 3 Oui Ni croyance ni appartenance NA NA Non Non Non Oui Oui Non Non 0.0
296 30 Homme Enseignement technique ou professionnel court 9356.39891 Exerce une profession Ouvrier qualifie 3 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Oui Non Non 1.0
297 32 Homme Enseignement technique ou professionnel court 1815.76553 Exerce une profession Employe 1 Non Rejet Moins important que le reste Satisfaction Non Non Non Oui Non Non Non 5.0
298 50 Femme Derniere annee d’etudes primaires 189.56697 Autre inactif Employe 0 Non Pratiquant occasionnel NA NA Non Non Non Non Oui Non Oui 6.0
299 23 Femme NA 11839.11870 Etudiant, eleve NA 2 Oui Ni croyance ni appartenance NA NA Non Non Non Oui Non Oui Non 4.0
300 49 Homme Enseignement superieur y compris technique superieur 8222.27349 Exerce une profession Profession intermediaire 1 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Non Non Oui 1.0
301 47 Femme 2eme cycle 1773.50953 Exerce une profession Employe 1 Non Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Non Non Non Oui 0.0
302 60 Femme Enseignement superieur y compris technique superieur 5908.78522 Au foyer Cadre 5 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Oui Non 0.4
303 56 Femme Derniere annee d’etudes primaires 6040.51233 Exerce une profession NA 2 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Non Non Non 0.0
304 68 Femme Enseignement superieur y compris technique superieur 4970.03148 Retraite Profession intermediaire 3 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 5.0
305 75 Homme 1er cycle 12618.12652 Retire des affaires NA 0 Ne sait pas Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 2.0
306 53 Femme Enseignement technique ou professionnel court 2342.71929 Au foyer Employe 2 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Oui 2.0
307 77 Femme Enseignement superieur y compris technique superieur 605.52146 Retraite Cadre 4 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Oui Oui 1.4
308 50 Femme 1er cycle 2435.15468 Exerce une profession Employe 11 Oui Pratiquant regulier Moins important que le reste Equilibre Non Non Non Oui Non Non Oui 3.0
309 36 Femme Enseignement superieur y compris technique superieur 1229.01187 Exerce une profession Cadre 4 Non Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Non Non Oui Non 2.0
310 59 Homme Enseignement technique ou professionnel long 9751.98403 Retraite Profession intermediaire 0 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Oui Oui 2.0
311 37 Femme Enseignement technique ou professionnel long 7095.56803 Exerce une profession Employe 1 Oui Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Oui Oui Non Non 5.0
312 22 Femme Enseignement superieur y compris technique superieur 6062.76946 Exerce une profession Employe 1 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Non Non 2.0
313 42 Homme Enseignement technique ou professionnel court 5124.08513 Exerce une profession Ouvrier qualifie 6 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 2.0
314 78 Homme Derniere annee d’etudes primaires 8241.67226 Retraite Employe 5 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 1.0
315 73 Homme Enseignement technique ou professionnel court 717.46036 Retraite Technicien 5 Oui NSP ou NVPR NA NA Non Non Non Oui Non Non Non 8.0
316 85 Femme Derniere annee d’etudes primaires 5019.42803 Retraite Employe 1 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 5.0
317 48 Femme 2eme cycle 4948.66007 Autre inactif Employe 6 Non Rejet NA NA Non Non Non Oui Oui Non Non 4.0
318 50 Homme Derniere annee d’etudes primaires 3954.33127 Exerce une profession NA 4 Non Pratiquant occasionnel Le plus important Satisfaction Non Non Non Non Non Non Non 1.0
319 39 Femme Enseignement superieur y compris technique superieur 7369.88179 Exerce une profession Cadre 1 Oui Pratiquant occasionnel Aussi important que le reste Satisfaction Non Oui Non Non Oui Non Non 0.7
320 33 Femme Enseignement technique ou professionnel long 1252.30692 Au foyer NA 4 Non Ni croyance ni appartenance NA NA Non Non Non Oui Non Non Non 3.0
321 25 Homme Enseignement technique ou professionnel long 7424.20649 Exerce une profession Employe 5 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Oui Non 2.1
322 33 Femme Enseignement technique ou professionnel long 3968.09179 Exerce une profession Employe 3 Non Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Non Non Non Non 0.0
323 36 Homme Enseignement technique ou professionnel court 13413.61695 Exerce une profession Ouvrier specialise 5 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Oui Oui Oui Non Oui 3.0
324 72 Homme Derniere annee d’etudes primaires 2243.72730 Retraite Ouvrier qualifie 1 Non Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 4.0
325 56 Homme Derniere annee d’etudes primaires 502.11162 Chomeur Ouvrier qualifie 4 Non Rejet NA NA Non Non Non Non Oui Non Non 3.0
326 57 Femme Enseignement technique ou professionnel court 1150.35083 Chomeur Employe 2 Oui Appartenance sans pratique NA NA Non Non Oui Oui Oui Non Oui 3.0
327 44 Homme Enseignement superieur y compris technique superieur 10536.17520 Exerce une profession Cadre 5 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Oui Non Oui Oui Oui 2.0
328 85 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 4069.28538 Retraite Employe 6 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 4.0
329 56 Femme 2eme cycle 6528.37095 Retraite Profession intermediaire 2 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Oui 0.0
330 27 Femme Enseignement superieur y compris technique superieur 6446.60640 Exerce une profession Cadre 2 Oui Appartenance sans pratique Aussi important que le reste Equilibre Non Oui Non Oui Non Oui Oui 1.0
331 64 Femme Derniere annee d’etudes primaires 1939.97350 Au foyer Employe 4 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 3.0
332 26 Femme Enseignement superieur y compris technique superieur 7973.26127 Exerce une profession Employe 1 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Non Oui Oui 1.4
333 49 Femme Enseignement superieur y compris technique superieur 9891.81649 Exerce une profession Cadre 5 Oui Pratiquant occasionnel NA NA Non Oui Non Non Non Non Non 1.0
334 74 Homme Enseignement technique ou professionnel court 8752.57996 Retraite Ouvrier qualifie 2 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 4.0
335 20 Homme Enseignement technique ou professionnel long 13195.64740 Exerce une profession Technicien 2 Oui Appartenance sans pratique Aussi important que le reste Equilibre Non Non Oui Oui Oui Oui Oui 2.0
336 51 Femme Enseignement technique ou professionnel court 3689.39720 Exerce une profession Technicien 1 Oui Appartenance sans pratique Peu important Insatisfaction Non Non Non Oui Non Non Oui 3.0
337 73 Homme Enseignement superieur y compris technique superieur 24031.21664 Retire des affaires NA 2 Oui Appartenance sans pratique NA NA Non Non Non Non Non Oui Oui 0.0
338 52 Homme Enseignement superieur y compris technique superieur 10836.75179 Exerce une profession NA 1 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Non Non 0.0
339 57 Homme Enseignement technique ou professionnel long 1743.14522 Exerce une profession Cadre 1 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Non Non Non 3.0
340 31 Femme 1er cycle 1455.45413 Chomeur Ouvrier specialise 7 Non Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 3.0
341 23 Homme NA 1713.09885 Etudiant, eleve NA 2 Oui Ni croyance ni appartenance NA NA Non Non Non Non Non Oui Oui 1.0
342 59 Femme Enseignement technique ou professionnel court 26983.52695 Autre inactif Profession intermediaire 2 Oui NSP ou NVPR NA NA Non Non Non Oui Oui Non Non 2.0
343 45 Homme 1er cycle 4594.60763 Exerce une profession Cadre 0 Ne sait pas Appartenance sans pratique Moins important que le reste Equilibre Non Non Oui Non Oui Non Non 2.0
344 39 Femme 2eme cycle 2928.97945 Exerce une profession Employe 3 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 0.0
345 47 Femme 1er cycle 2126.87696 Exerce une profession NA 2 Oui Ni croyance ni appartenance Le plus important Satisfaction Non Non Non Non Non Oui Non 0.7
346 18 Femme NA 1725.41023 Etudiant, eleve NA 9 Non Pratiquant regulier NA NA Non Non Non Non Non Oui Non 2.0
347 20 Homme 1er cycle 12698.59372 Chomeur Autre 3 Oui Rejet NA NA Non Non Non Non Oui Oui Oui 2.0
348 54 Femme Derniere annee d’etudes primaires 463.85819 Chomeur Ouvrier specialise 3 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 8.0
349 19 Homme NA 8175.78696 Etudiant, eleve NA 2 Non Ni croyance ni appartenance NA NA Non Non Oui Non Oui Oui Oui 1.0
350 36 Femme Enseignement technique ou professionnel court 1160.63832 Exerce une profession Ouvrier qualifie 3 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Oui Non Oui 2.0
351 41 Femme Enseignement technique ou professionnel court 4792.01034 Exerce une profession Employe 2 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Non 2.0
352 50 Homme Enseignement technique ou professionnel court 2378.06636 Exerce une profession Ouvrier qualifie 1 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Oui Non Non 3.0
353 52 Homme Enseignement technique ou professionnel court 2051.08424 Exerce une profession Profession intermediaire 1 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Oui Oui Oui Non Non 4.6
354 42 Femme Enseignement technique ou professionnel court 6058.08403 Exerce une profession Employe 3 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Oui Non 1.0
355 32 Homme Enseignement technique ou professionnel long 2204.04027 Exerce une profession Ouvrier qualifie 1 Non Ni croyance ni appartenance Moins important que le reste Insatisfaction Non Non Oui Non Non Non Non 3.0
356 54 Femme Derniere annee d’etudes primaires 2499.10005 Au foyer Ouvrier specialise 5 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 0.0
357 40 Femme 2eme cycle 2544.46340 Exerce une profession Employe 6 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Non Oui Non 3.0
358 20 Homme NA 9894.97377 Etudiant, eleve NA 1 Non Appartenance sans pratique NA NA Non Non Non Non Non Oui Oui 1.0
359 52 Homme 2eme cycle 5332.97218 Exerce une profession Technicien 7 Non Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Oui Oui Oui Oui Oui 2.0
360 41 Homme Enseignement technique ou professionnel long 3291.45844 Exerce une profession Profession intermediaire 2 Non NSP ou NVPR Moins important que le reste Satisfaction Non Non Non Non Non Oui Oui 1.0
361 51 Femme Enseignement technique ou professionnel court 1657.39611 Chomeur Ouvrier qualifie 5 Non Appartenance sans pratique NA NA Non Non Non Oui Non Oui Non 5.0
362 77 Homme 1er cycle 4178.88944 Retraite Cadre 1 Non Appartenance sans pratique NA NA Non Non Oui Non Oui Oui Oui 0.0
363 30 Homme Enseignement superieur y compris technique superieur 8314.26819 Exerce une profession Technicien 2 Oui Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Non Oui Oui Oui 4.0
364 69 Homme 1er cycle 469.35587 Retraite Employe 4 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 2.0
365 33 Femme Enseignement superieur y compris technique superieur 7484.55360 Au foyer Employe 1 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Oui 4.0
366 29 Homme Enseignement technique ou professionnel long 2611.59312 Exerce une profession Employe 2 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Oui Non Oui Non Non 3.0
367 22 Femme Enseignement technique ou professionnel court 6446.60640 Exerce une profession Profession intermediaire 3 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Non Non Oui 3.0
368 53 Femme Derniere annee d’etudes primaires 2793.45796 Autre inactif Ouvrier qualifie 1 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Oui 2.0
369 59 Femme Derniere annee d’etudes primaires 8136.99466 Autre inactif Employe 7 Non NSP ou NVPR NA NA Non Non Non Oui Non Non Non 1.0
370 36 Homme 1er cycle 1434.47541 Exerce une profession Ouvrier specialise 3 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Non Non Non 0.0
371 35 Homme Enseignement superieur y compris technique superieur 8551.49347 Exerce une profession Employe 4 Oui Rejet Moins important que le reste Equilibre Non Non Non Non Oui Oui Non 3.0
372 36 Femme Enseignement superieur y compris technique superieur 13102.36952 Exerce une profession Employe 1 Non Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Non Oui Oui Non 2.0
373 53 Homme 2eme cycle 3546.49620 Exerce une profession NA 3 Non NSP ou NVPR Aussi important que le reste Equilibre Non Non Non Oui Oui Oui Oui 2.0
374 87 Femme Derniere annee d’etudes primaires 620.07609 Retraite Autre 5 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 2.0
375 58 Femme Enseignement superieur y compris technique superieur 11920.31815 Au foyer Technicien 1 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Oui Non 3.0
376 29 Femme Enseignement superieur y compris technique superieur 9683.57638 Chomeur Technicien 0 Non Ni croyance ni appartenance NA NA Non Non Non Oui Non Oui Oui 2.0
377 18 Homme NA 11213.31216 Etudiant, eleve NA 1 Oui Rejet NA NA Non Non Non Non Non Oui Oui 1.4
378 22 Homme Enseignement technique ou professionnel court 14830.58383 Exerce une profession Ouvrier specialise 6 Non Ni croyance ni appartenance Peu important Satisfaction Non Non Non Non Non Oui Oui 5.0
379 26 Femme NA 14891.77337 Etudiant, eleve NA 3 Oui Ni croyance ni appartenance NA NA Non Non Non Non Non Oui Oui 2.0
380 31 Femme Enseignement superieur y compris technique superieur 2756.88131 Exerce une profession Employe 1 Non Rejet Le plus important Equilibre Non Non Non Non Non Oui Oui 3.0
381 71 Homme 2eme cycle 6708.95596 Retraite Employe 1 Oui Pratiquant occasionnel NA NA Non Non Non Non Oui Non Non 8.0
382 26 Femme NA 609.93821 Exerce une profession Employe 5 Oui Pratiquant regulier Moins important que le reste Equilibre Non Non Non Oui Non Oui Non 5.0
383 29 Femme Enseignement superieur y compris technique superieur 4736.77218 Exerce une profession Cadre 2 Non Pratiquant regulier Aussi important que le reste Insatisfaction Non Oui Non Non Oui Oui Non 2.0
384 28 Femme Enseignement superieur y compris technique superieur 6853.15984 Exerce une profession Employe 2 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Non Oui Oui 0.0
385 49 Femme 2eme cycle 8482.97942 Exerce une profession Cadre 3 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Oui Oui Non 1.4
386 33 Femme Enseignement technique ou professionnel court 3359.91732 Au foyer Ouvrier specialise 3 Non Ni croyance ni appartenance NA NA Non Non Non Non Oui Non Non 3.0
387 40 Femme Derniere annee d’etudes primaires 1377.17309 Chomeur Ouvrier specialise 5 Non Appartenance sans pratique NA NA Non Non Non Oui Non Oui Non 0.4
388 67 Femme Enseignement technique ou professionnel court 11724.96670 Retire des affaires NA 1 Non Appartenance sans pratique NA NA Non Non Non Non Oui Oui Oui 2.1
389 50 Femme Enseignement superieur y compris technique superieur 1119.40147 Exerce une profession Employe 0 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Non 1.0
390 29 Homme Derniere annee d’etudes primaires 1581.01485 Chomeur Ouvrier specialise 3 Non Appartenance sans pratique NA NA Non Non Oui Non Non Non Non 2.0
391 58 Femme Derniere annee d’etudes primaires 1345.96363 Autre inactif Employe 3 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 12.0
392 33 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 2985.77934 Au foyer Ouvrier specialise 3 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 6.0
393 22 Femme Enseignement technique ou professionnel long 9742.00106 Exerce une profession Employe 2 Non Pratiquant occasionnel Aussi important que le reste Equilibre Non Non Oui Oui Oui Non Oui 3.0
394 62 Femme Enseignement superieur y compris technique superieur 900.58071 Au foyer Cadre 1 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Oui Oui 3.0
395 19 Femme NA 7421.65110 Etudiant, eleve NA 1 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Oui Oui 3.0
396 51 Femme Enseignement technique ou professionnel court 1045.70641 Au foyer Ouvrier specialise 4 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 0.0
397 52 Femme Derniere annee d’etudes primaires 570.41626 Exerce une profession Employe 5 Non Rejet Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 3.0
398 60 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 1166.84185 Retraite Ouvrier specialise 10 Non Pratiquant regulier NA NA Non Non Non Non Oui Non Non 3.0
399 31 Femme Enseignement superieur y compris technique superieur 5825.48377 Chomeur Cadre 6 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Oui 0.0
400 53 Femme Derniere annee d’etudes primaires 845.69317 Exerce une profession Ouvrier qualifie 5 Non Appartenance sans pratique Peu important Equilibre Non Non Non Oui Non Non Non 0.6
401 44 Femme Enseignement superieur y compris technique superieur 2814.56228 Exerce une profession Cadre 6 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Non Oui Oui 0.6
402 35 Homme Enseignement technique ou professionnel court 3226.42609 Exerce une profession Ouvrier qualifie 2 Non Rejet Peu important Satisfaction Non Non Non Non Oui Non Non 2.0
403 68 Homme Derniere annee d’etudes primaires 9510.56235 Retire des affaires NA 0 Non Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 3.0
404 27 Homme 2eme cycle 23867.62510 Chomeur Ouvrier qualifie 0 Oui Rejet NA NA Non Non Non Non Non Oui Oui 0.0
405 70 Femme Derniere annee d’etudes primaires 9984.41426 Retire des affaires NA 1 Non Pratiquant occasionnel NA NA Non Non Oui Oui Non Non Oui 2.0
406 42 Homme 1er cycle 3991.23505 Exerce une profession Ouvrier specialise 2 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Oui Non Oui Non Non 2.0
407 19 Homme Enseignement technique ou professionnel long 3151.21926 Chomeur Ouvrier specialise 2 Non Appartenance sans pratique NA NA Non Non Oui Oui Non Oui Oui 4.0
408 66 Femme N’a jamais fait d’etudes 3192.37881 Au foyer NA 3 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 4.0
409 46 Homme Enseignement superieur y compris technique superieur 6587.14598 Exerce une profession Cadre 0 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 2.0
410 77 Femme 1er cycle 5188.08690 Retire des affaires NA 0 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 1.0
411 42 Homme Enseignement technique ou professionnel court 3104.63683 Exerce une profession Profession intermediaire 3 Oui Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Non Non Non Oui 2.0
412 22 Femme NA 2260.45841 Etudiant, eleve NA 2 Oui Pratiquant regulier NA NA Non Non Non Oui Non Non Oui 2.0
413 35 Femme Enseignement technique ou professionnel court 9336.18291 Exerce une profession Ouvrier specialise 3 Oui Pratiquant occasionnel Moins important que le reste Insatisfaction Non Non Non Non Non Oui Non 3.0
414 37 Femme Enseignement technique ou professionnel court 8690.75572 Exerce une profession Employe 7 Non Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Non Oui Oui Non 0.0
415 23 Homme Enseignement technique ou professionnel long 888.20199 Exerce une profession Employe 4 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Oui 0.0
416 64 Homme Enseignement superieur y compris technique superieur 1043.81666 Retraite Cadre 2 Non Appartenance sans pratique NA NA Non Non Non Oui Oui Oui Oui 3.0
417 29 Femme Enseignement technique ou professionnel long 194.44285 Chomeur Ouvrier specialise 3 Non Ni croyance ni appartenance NA NA Non Non Non Oui Oui Oui Non 4.0
418 58 Homme N’a jamais fait d’etudes 1737.17403 Retraite Ouvrier qualifie 2 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 1.0
419 39 Homme Enseignement technique ou professionnel court 6721.53253 Exerce une profession Profession intermediaire 1 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Oui Oui Non 3.0
420 39 Homme Enseignement technique ou professionnel court 6822.87710 Exerce une profession Ouvrier specialise 3 Oui Ni croyance ni appartenance Aussi important que le reste Insatisfaction Non Non Oui Oui Oui Non Oui 3.0
421 73 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 18190.65372 Retraite Employe 2 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 10.0
422 57 Homme Enseignement technique ou professionnel court 5988.20683 Exerce une profession Profession intermediaire 0 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Non Non 3.0
423 57 Homme Derniere annee d’etudes primaires 1879.08794 Autre inactif Ouvrier qualifie 3 Non Appartenance sans pratique NA NA Non Non Oui Non Oui Non Non 4.0
424 57 Femme Derniere annee d’etudes primaires 3963.18408 Exerce une profession Employe 1 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Non 0.0
425 44 Femme Enseignement technique ou professionnel court 2234.11813 Exerce une profession Ouvrier specialise 1 Oui Ni croyance ni appartenance Peu important Equilibre Non Non Non Oui Non Oui Non 2.0
426 66 Femme N’a jamais fait d’etudes 2147.84106 Retraite Technicien 5 Non Pratiquant regulier NA NA Non Non Non Non Oui Non Non 10.0
427 19 Homme Enseignement technique ou professionnel court 2472.31233 Exerce une profession Ouvrier specialise 7 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Oui 0.4
428 24 Homme Enseignement superieur y compris technique superieur 8569.68033 Exerce une profession Technicien 1 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Non Oui 0.0
429 32 Femme 2eme cycle 5907.34751 Chomeur Employe 0 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 5.0
430 40 Femme Enseignement technique ou professionnel court 9178.11612 Exerce une profession Employe 4 Non Pratiquant occasionnel Aussi important que le reste Equilibre Non Non Non Non Non Non Oui 0.0
431 44 Homme Derniere annee d’etudes primaires 1610.88968 Exerce une profession Profession intermediaire 4 Non Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Oui Non Non Oui Non 3.0
432 26 Femme 2eme cycle 6809.89950 Chomeur Employe 2 Non Ni croyance ni appartenance NA NA Non Non Non Non Oui Non Non 1.0
433 40 Femme 1er cycle 4540.62082 Exerce une profession Profession intermediaire 3 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Non 1.0
434 36 Femme 2eme cycle 16548.67114 Au foyer Cadre 11 Non Pratiquant regulier NA NA Non Non Non Non Non Oui Non 1.1
435 72 Femme Enseignement superieur y compris technique superieur 693.12945 Retraite Cadre 1 Oui Pratiquant occasionnel NA NA Non Non Non Oui Oui Oui Non 0.0
436 29 Femme 2eme cycle 6319.54233 Exerce une profession NA 2 Oui Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Oui Oui Oui Oui Oui 0.0
437 35 Homme Enseignement technique ou professionnel court 7671.19631 Exerce une profession Ouvrier qualifie 3 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Oui Non Oui 1.0
438 72 Homme Derniere annee d’etudes primaires 1901.39620 Retraite Ouvrier specialise 3 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 4.0
439 57 Femme 1er cycle 1236.73264 Autre inactif Employe 4 Oui Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 5.0
440 40 Femme Enseignement superieur y compris technique superieur 3433.18492 Exerce une profession Cadre 3 Oui Pratiquant regulier Moins important que le reste Insatisfaction Non Non Oui Non Non Oui Oui 0.9
441 60 Femme Enseignement technique ou professionnel court 9280.53471 Retraite Employe 1 Oui Pratiquant regulier NA NA Non Non Non Oui Non Oui Non 2.0
442 36 Femme Enseignement technique ou professionnel court 3082.67179 Exerce une profession Employe 4 Non NSP ou NVPR Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Non 2.0
443 54 Homme N’a jamais fait d’etudes 10392.45857 Autre inactif Ouvrier specialise 9 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 4.0
444 21 Femme NA 2405.38391 Exerce une profession Employe 2 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Non Oui Non 0.7
445 25 Femme Enseignement superieur y compris technique superieur 11050.06292 Etudiant, eleve NA 0 Oui Appartenance sans pratique NA NA Non Non Non Non Non Oui Oui 0.0
446 34 Homme Enseignement technique ou professionnel court 14983.11518 Exerce une profession Ouvrier specialise 3 Oui Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Oui Non Non Non Non 1.0
447 51 Femme Enseignement technique ou professionnel court 4426.97514 Autre inactif Ouvrier qualifie 2 Non Appartenance sans pratique NA NA Non Non Non Non Non Oui Non 5.0
448 64 Homme 1er cycle 8411.92320 Retraite Ouvrier qualifie 1 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 0.0
449 32 Homme NA 6310.79892 Chomeur Autre 2 Oui NSP ou NVPR NA NA Non Non Non Non Non Non Non 0.0
450 24 Femme Enseignement technique ou professionnel long 6352.83859 Chomeur Employe 1 Non Appartenance sans pratique NA NA Non Non Non Oui Oui Oui Oui 4.0
451 35 Femme Enseignement technique ou professionnel court 9657.99595 Au foyer Employe 4 Non Ni croyance ni appartenance NA NA Non Non Non Oui Non Oui Oui 2.0
452 35 Femme Enseignement technique ou professionnel court 3098.42253 Exerce une profession Employe 1 Oui Ni croyance ni appartenance Moins important que le reste Insatisfaction Non Non Non Non Non Oui Non 1.0
453 19 Homme NA 4443.46418 Etudiant, eleve NA 1 Oui Appartenance sans pratique NA NA Non Non Non Non Non Oui Oui 0.0
454 50 Femme 2eme cycle 3436.36088 Au foyer Employe 2 Non Pratiquant occasionnel NA NA Non Non Non Oui Oui Non Non 5.0
455 28 Homme NA 9354.26753 Etudiant, eleve Employe 1 Non Ni croyance ni appartenance NA NA Non Non Non Oui Oui Oui Oui 1.0
456 64 Homme N’a jamais fait d’etudes 3560.02133 Retraite Ouvrier specialise 4 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 1.0
457 57 Homme Enseignement technique ou professionnel long 4794.21618 Chomeur Profession intermediaire 2 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 5.0
458 56 Homme Enseignement superieur y compris technique superieur 3244.10615 Exerce une profession NA 2 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Oui Non Non 0.4
459 78 Femme Derniere annee d’etudes primaires 6259.80712 Retraite Employe 2 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 4.0
460 39 Femme Enseignement technique ou professionnel court 3029.04202 Exerce une profession Employe 1 Non Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Oui Non Oui Non 4.0
461 27 Femme Enseignement technique ou professionnel long 16098.20045 Au foyer Employe 2 Oui Ni croyance ni appartenance NA NA Non Non Oui Oui Non Oui Oui 2.0
462 47 Homme 2eme cycle 1621.77240 Exerce une profession Profession intermediaire 1 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Oui Non Oui 2.0
463 54 Femme Enseignement superieur y compris technique superieur 1194.07886 Exerce une profession Cadre 1 Oui Rejet Moins important que le reste Satisfaction Non Non Non Oui Non Non Non 2.0
464 81 Femme Derniere annee d’etudes primaires 2916.92540 Retraite Employe 4 Oui Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 1.0
465 41 Femme Enseignement superieur y compris technique superieur 6099.73892 Exerce une profession Cadre 1 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Non Oui Oui 1.4
466 38 Femme 2eme cycle 8727.14870 Exerce une profession Ouvrier qualifie 2 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Non Oui Oui 1.0
467 37 Femme Enseignement superieur y compris technique superieur 10164.74110 Exerce une profession Employe 2 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 0.6
468 54 Femme Derniere annee d’etudes primaires 5476.15029 Exerce une profession Employe 8 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Non Non 3.0
469 38 Homme 2eme cycle 3611.14686 Exerce une profession Profession intermediaire 0 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 4.0
470 40 Femme Enseignement superieur y compris technique superieur 1387.68058 Exerce une profession Cadre 3 Non Appartenance sans pratique Peu important Equilibre Non Non Oui Non Oui Oui Non 0.7
471 32 Femme Enseignement technique ou professionnel court 5703.31871 Au foyer Ouvrier qualifie 4 Ne sait pas Ni croyance ni appartenance NA NA Non Non Non Oui Non Non Oui 3.0
472 38 Homme Enseignement superieur y compris technique superieur 2898.45874 Exerce une profession Technicien 5 Non Pratiquant regulier Moins important que le reste Equilibre Non Non Non Non Oui Non Oui 3.0
473 39 Homme Enseignement technique ou professionnel court 4273.89328 Exerce une profession Technicien 5 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Oui 1.1
474 23 Homme NA 4485.27844 Etudiant, eleve NA 4 Non Pratiquant occasionnel NA NA Non Non Non Non Oui Oui Oui 2.0
475 62 Femme Enseignement technique ou professionnel long 1022.90987 Retraite Employe 4 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 3.0
476 39 Femme 2eme cycle 2687.28114 Exerce une profession Profession intermediaire 1 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Oui Non 2.0
477 50 Femme Enseignement technique ou professionnel court 8233.92116 Au foyer Employe 1 Non Appartenance sans pratique NA NA Non Non Non Oui Non Oui Oui 2.0
478 35 Homme Enseignement technique ou professionnel court 9000.59787 Exerce une profession Ouvrier qualifie 2 Oui Rejet Moins important que le reste Equilibre Non Non Non Non Non Oui Non 3.0
479 33 Homme Enseignement technique ou professionnel court 8368.88107 Exerce une profession Technicien 1 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Oui Oui Oui Non Oui 3.0
480 78 Femme 1er cycle 7312.43455 Au foyer NA 2 Non Pratiquant occasionnel NA NA Non Non Non Oui Oui Non Non 3.0
481 47 Femme Derniere annee d’etudes primaires 2334.28725 Exerce une profession Employe 6 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Oui Non Non Non Non 3.0
482 48 Femme Derniere annee d’etudes primaires 835.70647 Au foyer Ouvrier specialise 2 Oui Pratiquant regulier NA NA Non Non Non Oui Oui Non Oui 3.0
483 62 Femme Derniere annee d’etudes primaires 401.14929 Exerce une profession Employe 1 Oui NSP ou NVPR Moins important que le reste Insatisfaction Non Non Non Oui Oui Non Non 2.0
484 37 Femme Enseignement superieur y compris technique superieur 2236.79269 Exerce une profession NA 1 Non Ni croyance ni appartenance Moins important que le reste Insatisfaction Non Non Non Oui Oui Oui Oui 1.4
485 52 Homme 1er cycle 1484.20198 Autre inactif Ouvrier specialise 8 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 1.0
486 62 Femme Derniere annee d’etudes primaires 1286.75140 Retraite Ouvrier qualifie 7 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 4.0
487 52 Homme Enseignement superieur y compris technique superieur 2007.28538 Exerce une profession Cadre 2 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Oui Oui Oui Non Non 0.4
488 20 Homme NA 11485.34056 Etudiant, eleve NA 2 Oui Appartenance sans pratique NA NA Non Oui Non Oui Non Oui Oui 0.0
489 56 Femme Enseignement superieur y compris technique superieur 2677.21453 Retraite Cadre 2 Non Ni croyance ni appartenance NA NA Non Non Non Non Oui Non Non 4.0
490 23 Femme 2eme cycle 3426.57992 Exerce une profession Employe 4 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Non Oui Non 1.0
491 73 Femme N’a jamais fait d’etudes 2759.58067 Autre inactif Ouvrier specialise 3 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 4.0
492 34 Homme Enseignement superieur y compris technique superieur 78.07834 Exerce une profession Employe 9 Non Pratiquant regulier Peu important Equilibre Non Oui Oui Oui Oui Oui Oui 1.0
493 47 Femme Enseignement technique ou professionnel court 3032.38414 Exerce une profession Employe 1 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Oui Non Non 1.0
494 40 Homme 2eme cycle 1038.21685 Exerce une profession Cadre 4 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 3.0
495 82 Femme Enseignement technique ou professionnel court 5014.43511 Retraite Employe 1 Ne sait pas Pratiquant regulier NA NA Non Non Non Non Non Non Oui 3.0
496 20 Femme NA 14228.21378 Etudiant, eleve NA 2 Oui Pratiquant occasionnel NA NA Non Non Non Oui Oui Oui Oui 2.0
497 42 Homme Enseignement technique ou professionnel court 7008.74857 Exerce une profession Ouvrier qualifie 3 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Non Non 0.0
498 38 Femme Enseignement superieur y compris technique superieur 952.94773 Exerce une profession Cadre 1 Non Pratiquant occasionnel Aussi important que le reste Equilibre Non Non Non Oui Non Non Oui 0.0
499 56 Homme Enseignement technique ou professionnel court 1461.80249 Exerce une profession Ouvrier qualifie 2 Oui Pratiquant regulier Moins important que le reste Equilibre Non Non Non Oui Oui Non Non 2.0
500 63 Homme Derniere annee d’etudes primaires 2290.05819 Retraite Technicien 1 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 5.0
501 77 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 2151.26932 Retraite Ouvrier qualifie 6 Non Ni croyance ni appartenance NA NA Non Non Non Oui Non Non Non 0.0
502 44 Homme Derniere annee d’etudes primaires 1180.50684 Exerce une profession Ouvrier qualifie 3 Non Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Non Oui Non Non 2.0
503 30 Homme Enseignement superieur y compris technique superieur 14755.43868 Exerce une profession Employe 8 Non Rejet Moins important que le reste Insatisfaction Non Non Non Oui Oui Oui Non 3.0
504 40 Femme 1er cycle 14201.23880 Exerce une profession Employe 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 2.0
505 44 Femme Enseignement technique ou professionnel court 3190.33875 Exerce une profession Employe 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Non Oui 3.0
506 60 Homme Enseignement superieur y compris technique superieur 1781.37958 Exerce une profession NA 3 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 1.0
507 58 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 820.59817 Autre inactif Ouvrier specialise 5 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 4.0
508 60 Homme Enseignement technique ou professionnel court 3832.53846 Retraite Ouvrier qualifie 1 Oui Ni croyance ni appartenance NA NA Non Non Non Non Oui Non Non 4.0
509 77 Femme 1er cycle 12156.75299 Retraite Cadre 6 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 3.0
510 72 Homme Derniere annee d’etudes primaires 1974.33010 Retraite Ouvrier specialise 7 Oui Appartenance sans pratique NA NA Non Non Oui Oui Non Non Oui 4.0
511 18 Homme NA 2448.16200 Etudiant, eleve NA 6 Non Pratiquant regulier NA NA Non Non Non Non Oui Oui Oui 3.0
512 38 Femme 2eme cycle 5360.54406 Exerce une profession Profession intermediaire 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Non 3.0
513 51 Homme Enseignement technique ou professionnel long 5846.34785 Exerce une profession Profession intermediaire 3 Non Pratiquant regulier Moins important que le reste Equilibre Non Non Oui Non Non Non Oui 3.0
514 58 Femme Derniere annee d’etudes primaires 802.00737 Autre inactif NA 1 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 3.0
515 35 Femme Enseignement superieur y compris technique superieur 8496.84882 Exerce une profession Employe 3 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Oui Non Oui 2.0
516 37 Homme Enseignement technique ou professionnel court 2804.51064 Exerce une profession Ouvrier qualifie 4 Oui Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Non Oui Oui Non 3.0
517 54 Femme Enseignement superieur y compris technique superieur 6013.76986 Exerce une profession Autre 2 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Non Oui 2.0
518 46 Homme Derniere annee d’etudes primaires 1444.01272 Exerce une profession Ouvrier qualifie 2 Non Pratiquant occasionnel Aussi important que le reste Insatisfaction Non Non Non Oui Non Non Non 3.0
519 58 Homme Enseignement technique ou professionnel court 1505.37154 Retraite Ouvrier qualifie 1 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 3.0
520 30 Femme Enseignement technique ou professionnel court 4607.50832 Chomeur Ouvrier specialise 3 Non Ni croyance ni appartenance NA NA Non Non Non Oui Non Oui Non 0.0
521 61 Homme Enseignement superieur y compris technique superieur 2983.06963 Retraite Cadre 3 Non Appartenance sans pratique NA NA Non Non Oui Oui Non Non Non 1.0
522 43 Femme Enseignement technique ou professionnel court 1671.76251 Exerce une profession Employe 4 Non Pratiquant regulier Moins important que le reste Insatisfaction Non Non Non Non Non Oui Non 2.0
523 43 Homme Enseignement technique ou professionnel court 8741.97456 Exerce une profession Autre 3 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Oui Non Non 3.0
524 63 Homme 1er cycle 7002.89890 Retraite Ouvrier specialise 3 Oui Pratiquant occasionnel NA NA Non Non Oui Oui Non Non Non 0.0
525 88 Homme Derniere annee d’etudes primaires 5046.41533 Retraite Ouvrier qualifie 8 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 2.0
526 45 Homme Enseignement technique ou professionnel court 3799.84175 Autre inactif Employe 1 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 5.0
527 58 Homme Derniere annee d’etudes primaires 1517.40659 Exerce une profession Ouvrier qualifie 4 Oui Pratiquant regulier Aussi important que le reste Equilibre Non Non Non Non Oui Non Non 2.0
528 39 Femme 1er cycle 7859.12669 Exerce une profession Ouvrier specialise 9 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Oui Oui Non 0.7
529 71 Femme 2eme cycle 6889.07086 Retraite Employe 2 Oui Pratiquant regulier NA NA Non Non Non Non Oui Oui Oui 3.0
530 39 Homme 2eme cycle 4228.61164 Exerce une profession Profession intermediaire 2 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Oui Non Non 2.0
531 56 Homme Enseignement technique ou professionnel court 2400.98611 Exerce une profession Employe 1 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Oui Oui Oui 0.7
532 53 Homme Derniere annee d’etudes primaires 1239.40043 Chomeur Ouvrier qualifie 7 Non Appartenance sans pratique NA NA Non Non Oui Non Oui Non Non 0.3
533 34 Femme Derniere annee d’etudes primaires 3701.23693 Au foyer NA 7 Non Pratiquant regulier NA NA Non Non Non Oui Oui Non Oui 3.0
534 24 Femme Enseignement technique ou professionnel court 5621.27468 Chomeur Employe 7 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Oui 2.0
535 46 Femme Enseignement technique ou professionnel court 6240.30820 Exerce une profession Employe 8 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Oui Oui Non 1.0
536 30 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 7151.03343 Exerce une profession Employe 4 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Oui Non Non 0.0
537 38 Homme Enseignement technique ou professionnel court 1908.49470 Exerce une profession Ouvrier specialise 8 Oui Appartenance sans pratique Peu important Insatisfaction Non Non Non Non Non Non Non 0.3
538 59 Homme Enseignement superieur y compris technique superieur 960.90262 Exerce une profession Cadre 7 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Non Oui 5.0
539 30 Femme Enseignement superieur y compris technique superieur 3329.39704 Exerce une profession Profession intermediaire 1 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Non Oui Oui 1.0
540 69 Homme Enseignement technique ou professionnel court 2141.41551 Retraite Ouvrier qualifie 5 Oui Pratiquant occasionnel NA NA Non Non Non Non Oui Non Non 0.0
541 31 Homme Enseignement superieur y compris technique superieur 6388.49891 Exerce une profession Cadre 1 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Oui Non Oui 3.0
542 55 Femme Enseignement technique ou professionnel court 1536.32859 Exerce une profession Employe 4 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 1.0
543 44 Femme 1er cycle 8774.86974 Exerce une profession Employe 3 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Non 7.0
544 22 Femme Enseignement technique ou professionnel court 13480.67822 Exerce une profession Employe 1 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Non Non Non 2.0
545 61 Homme Enseignement superieur y compris technique superieur 5603.27830 Exerce une profession NA 3 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Non Non Oui 2.0
546 41 Homme Enseignement technique ou professionnel court 6224.54980 Exerce une profession Ouvrier specialise 4 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Oui Non Oui 2.0
547 43 Homme Enseignement technique ou professionnel court 3829.48166 Exerce une profession Ouvrier qualifie 0 Oui Rejet Moins important que le reste Insatisfaction Non Non Non Non Oui Non Oui 3.0
548 53 Homme 1er cycle 4994.72400 Exerce une profession Ouvrier qualifie 1 Non Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Oui Non Oui Non Non 2.1
549 41 Homme Enseignement superieur y compris technique superieur 2833.72224 Exerce une profession Cadre 2 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Oui Oui 2.0
550 77 Homme Derniere annee d’etudes primaires 10309.64250 Retraite Ouvrier qualifie 1 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 4.0
551 84 Femme Derniere annee d’etudes primaires 3210.74430 Retraite Ouvrier qualifie 1 Ne sait pas Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 2.0
552 60 Homme Enseignement superieur y compris technique superieur 5699.75924 Exerce une profession Cadre 4 Oui Pratiquant regulier Aussi important que le reste Equilibre Non Non Oui Non Non Oui Oui 0.1
553 38 Femme Enseignement technique ou professionnel court 4233.37037 Exerce une profession Employe 4 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Non Oui Oui 2.0
554 35 Homme Enseignement technique ou professionnel court 1853.07026 Exerce une profession Technicien 2 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Oui Oui Oui 2.0
555 39 Homme Enseignement technique ou professionnel long 19493.50009 Exerce une profession Employe 3 Oui Pratiquant regulier Aussi important que le reste Insatisfaction Non Non Oui Oui Non Oui Non 2.0
556 68 Homme 2eme cycle 4486.89566 Retraite Profession intermediaire 6 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Oui 2.0
557 46 Homme Enseignement superieur y compris technique superieur 1081.59974 Chomeur NA 15 Oui Rejet NA NA Non Non Non Oui Non Non Non 2.0
558 48 Homme Enseignement superieur y compris technique superieur 7891.36280 Exerce une profession Cadre 1 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Non Oui 0.0
559 24 Homme Enseignement superieur y compris technique superieur 2968.67629 Chomeur Ouvrier specialise 5 Oui Pratiquant occasionnel NA NA Non Non Non Non Oui Oui Non 3.0
560 57 Homme Derniere annee d’etudes primaires 1339.06124 Retraite Ouvrier qualifie 4 Oui Pratiquant occasionnel NA NA Non Non Non Oui Oui Non Oui 5.0
561 63 Homme Enseignement technique ou professionnel court 1812.08563 Retraite Ouvrier qualifie 3 Non Pratiquant occasionnel NA NA Non Non Non Oui Oui Non Non 4.0
562 37 Femme 1er cycle 15027.02909 Au foyer Employe 4 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 2.0
563 59 Homme Enseignement technique ou professionnel court 1645.55351 Retraite Profession intermediaire 2 Non Appartenance sans pratique NA NA Non Non Oui Non Oui Non Non 0.9
564 82 Homme Derniere annee d’etudes primaires 1321.50101 Retraite Ouvrier qualifie 3 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 1.0
565 28 Femme 1er cycle 15219.68351 Au foyer Ouvrier specialise 7 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 0.0
566 67 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 6077.69870 Retire des affaires NA 2 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 5.0
567 48 Homme 1er cycle 912.89633 Chomeur Ouvrier specialise 6 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 0.0
568 54 Femme Derniere annee d’etudes primaires 1546.29086 Exerce une profession Ouvrier qualifie 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Non Non 0.0
569 54 Homme Enseignement superieur y compris technique superieur 4004.70226 Exerce une profession Employe 5 Non Ni croyance ni appartenance Peu important Satisfaction Non Non Non Non Oui Oui Oui 2.0
570 80 Femme 2eme cycle 7624.31229 Retraite Cadre 1 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 2.0
571 55 Homme Derniere annee d’etudes primaires 8955.04879 Chomeur Ouvrier qualifie 7 Non Ni croyance ni appartenance NA NA Non Non Oui Non Oui Non Non 4.0
572 36 Homme Enseignement technique ou professionnel court 7308.50430 Exerce une profession Ouvrier qualifie 2 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Oui Oui Non 2.1
573 66 Homme Derniere annee d’etudes primaires 16353.25845 Retire des affaires NA 0 Oui Rejet NA NA Non Non Non Non Oui Non Non 2.0
574 31 Femme 2eme cycle 11906.47417 Exerce une profession Employe 3 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Non Non 1.0
575 50 Homme Enseignement technique ou professionnel long 2438.26388 Exerce une profession Cadre 6 Non Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Non Non Oui Oui Oui 0.0
576 22 Femme Enseignement technique ou professionnel court 13706.31968 Exerce une profession Employe 2 Non Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Oui Oui Oui Oui 2.0
577 73 Femme 2eme cycle 14946.31635 Retraite Employe 1 Oui Pratiquant regulier NA NA Non Non Non Non Oui Non Non 3.0
578 19 Femme 1er cycle 8654.38669 Exerce une profession NA 0 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Non Non Non 6.0
579 32 Femme Enseignement technique ou professionnel court 5783.46143 Chomeur Employe 4 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Oui Non 1.0
580 60 Femme 1er cycle 885.44705 Retraite Employe 13 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 3.0
581 47 Homme Enseignement superieur y compris technique superieur 10426.93772 Exerce une profession Employe 4 Non Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Oui Oui Oui Oui 0.3
582 28 Femme Enseignement technique ou professionnel court 1391.47106 Exerce une profession Employe 0 Non Pratiquant occasionnel Aussi important que le reste Equilibre Non Non Non Oui Non Non Non 5.0
583 30 Femme Enseignement superieur y compris technique superieur 6310.44518 Exerce une profession Employe 2 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Non Oui Non 4.0
584 75 Femme 1er cycle 2119.84024 Retraite Employe 1 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 3.0
585 48 Femme Enseignement technique ou professionnel court 1116.03089 Exerce une profession Employe 7 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Non Non 1.0
586 58 Homme Derniere annee d’etudes primaires 7282.49829 Exerce une profession NA 2 Non Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Non Non Non Non 1.0
587 45 Femme 2eme cycle 7364.75486 Au foyer Employe 5 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 1.0
588 73 Femme Derniere annee d’etudes primaires 5843.33345 Retraite Ouvrier specialise 7 Non NSP ou NVPR NA NA Non Non Non Non Non Non Non 6.0
589 48 Femme 2eme cycle 1480.35594 Exerce une profession Employe 9 Non Pratiquant regulier Moins important que le reste Equilibre Non Non Non Oui Non Non Oui 0.4
590 28 Homme Enseignement technique ou professionnel court 18639.52145 Exerce une profession Ouvrier specialise 7 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Oui Oui Non Oui Non 4.0
591 33 Homme Enseignement technique ou professionnel court 3409.59719 Exerce une profession Technicien 6 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Non Non Non 3.0
592 63 Homme 1er cycle 9867.03424 Retraite Profession intermediaire 6 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 3.0
593 39 Femme 2eme cycle 905.82964 Au foyer Employe 9 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 3.0
594 31 Femme Enseignement superieur y compris technique superieur 6000.95811 Exerce une profession Profession intermediaire 0 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Non Non Non 0.1
595 52 Homme 1er cycle 1155.33507 Autre inactif Ouvrier qualifie 2 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 5.0
596 32 Homme Enseignement superieur y compris technique superieur 7024.97942 Exerce une profession Cadre 6 Non Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 0.1
597 32 Homme Enseignement technique ou professionnel court 7514.76413 Exerce une profession Ouvrier qualifie 3 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Oui Oui Oui Non Non 4.0
598 44 Femme Enseignement superieur y compris technique superieur 468.64137 Chomeur Employe 4 Oui Appartenance sans pratique NA NA Non Non Non Oui Oui Oui Oui 1.0
599 50 Femme Enseignement superieur y compris technique superieur 1278.40219 Exerce une profession Profession intermediaire 4 Oui Pratiquant regulier Aussi important que le reste Satisfaction Non Non Non Non Non Non Non 3.0
600 45 Homme Enseignement superieur y compris technique superieur 3411.29435 Exerce une profession Cadre 2 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Oui Non Oui Non Oui 1.0
601 84 Homme Enseignement technique ou professionnel court 4268.93799 Retraite Ouvrier qualifie 2 Oui Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 2.0
602 54 Femme 1er cycle 2046.13748 Au foyer Employe 2 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 4.0
603 50 Homme Enseignement superieur y compris technique superieur 358.18111 Exerce une profession Employe 3 Oui Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Non Oui Non Non 0.3
604 37 Femme Enseignement technique ou professionnel long 3745.47385 Au foyer Employe 7 Non Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 2.0
605 25 Homme Enseignement technique ou professionnel court 2969.28214 Exerce une profession Ouvrier specialise 2 Oui Ni croyance ni appartenance Moins important que le reste Insatisfaction Non Non Oui Non Oui Oui Non 0.9
606 38 Femme Enseignement technique ou professionnel long 6308.14479 Exerce une profession Technicien 6 Non Appartenance sans pratique Le plus important Satisfaction Non Non Non Non Non Non Non 1.0
607 23 Femme Enseignement superieur y compris technique superieur 2905.27279 Exerce une profession Cadre 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Oui Oui 0.4
608 38 Homme N’a jamais fait d’etudes 1537.28455 Exerce une profession Ouvrier specialise 3 Non Pratiquant regulier Aussi important que le reste Equilibre Non Non Non Non Non Non Non 1.0
609 48 Homme Derniere annee d’etudes primaires 1624.32833 Exerce une profession Ouvrier specialise 4 Non Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Oui Non Non Non Non 2.9
610 66 Homme Enseignement superieur y compris technique superieur 13590.63983 Retire des affaires Cadre 2 Oui Pratiquant regulier NA NA Non Non Non Non Oui Non Oui 3.0
611 50 Homme 2eme cycle 796.18708 Autre inactif Ouvrier qualifie 4 Oui Appartenance sans pratique NA NA Non Non Non Oui Oui Non Non 4.0
612 56 Femme Enseignement technique ou professionnel long 6408.42927 Exerce une profession Employe 3 Oui Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Non Non Non Oui Oui 0.6
613 26 Femme Enseignement superieur y compris technique superieur 7147.28264 Exerce une profession Employe 0 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Oui Non Oui 1.0
614 30 Homme 2eme cycle 3840.46437 Exerce une profession NA 2 Non Appartenance sans pratique Le plus important Equilibre Non Non Non Non Non Non Non 2.0
615 80 Femme Derniere annee d’etudes primaires 4166.98273 Au foyer Technicien 3 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 2.0
616 49 Homme Enseignement superieur y compris technique superieur 1875.22145 Exerce une profession Cadre 3 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Oui 3.0
617 74 Homme Derniere annee d’etudes primaires 1662.29722 Retraite NA 1 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Oui Oui 3.0
618 35 Femme 1er cycle 3836.73041 Au foyer Employe 2 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Oui Oui 3.0
619 62 Femme 2eme cycle 6696.97108 Retraite Employe 3 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Oui 1.0
620 74 Femme Derniere annee d’etudes primaires 14281.79747 Retire des affaires NA 1 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 1.0
621 50 Femme Enseignement superieur y compris technique superieur 5113.94754 Exerce une profession Technicien 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Oui Oui 0.0
622 70 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 6561.44543 Retraite NA 2 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 4.0
623 57 Femme N’a jamais fait d’etudes 2379.16822 Exerce une profession Employe 7 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Non Non 2.0
624 33 Femme Enseignement superieur y compris technique superieur 14685.43134 Exerce une profession Cadre 0 Oui Pratiquant regulier Aussi important que le reste Satisfaction Non Non Non Non Non Non Non 0.9
625 63 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 1866.58048 Retraite Ouvrier specialise 5 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 6.0
626 40 Femme Enseignement technique ou professionnel court 1247.68540 Autre inactif Employe 1 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 2.0
627 30 Femme Enseignement superieur y compris technique superieur 7323.99917 Exerce une profession Profession intermediaire 1 Oui Rejet Moins important que le reste Satisfaction Non Oui Non Oui Oui Non Non 2.0
628 61 Homme NA 6788.95277 Retraite Ouvrier qualifie 8 Oui Appartenance sans pratique NA NA Non Non Oui Non Oui Non Oui 2.0
629 39 Femme Enseignement superieur y compris technique superieur 3550.30970 Exerce une profession Employe 1 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 1.0
630 29 Femme Enseignement superieur y compris technique superieur 5841.66106 Chomeur Profession intermediaire 10 Non Pratiquant regulier NA NA Non Non Non Non Non Oui Non 4.0
631 53 Homme Enseignement technique ou professionnel court 5827.01295 Exerce une profession Ouvrier qualifie 2 Oui Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Non Oui Non Non 0.3
632 42 Homme Enseignement superieur y compris technique superieur 1965.95066 Exerce une profession Cadre 3 Non Pratiquant regulier Moins important que le reste Insatisfaction Non Non Non Oui Non Non Oui 0.0
633 54 Femme Derniere annee d’etudes primaires 8439.80977 Exerce une profession Profession intermediaire 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Oui Non 2.0
634 33 Femme N’a jamais fait d’etudes 4336.49437 Au foyer NA 7 Non Pratiquant occasionnel NA NA Non Non Non Oui Oui Non Non 3.0
635 28 Femme Enseignement superieur y compris technique superieur 8094.24430 Exerce une profession Cadre 2 Non Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Oui Non Non Oui 1.0
636 45 Femme 1er cycle 1018.13128 Autre inactif Ouvrier specialise 8 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 3.0
637 51 Femme Derniere annee d’etudes primaires 3626.03917 Exerce une profession Employe 7 Oui Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Oui Non Oui Non 3.0
638 39 Femme Enseignement superieur y compris technique superieur 3912.49163 Exerce une profession Cadre 0 Oui Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Oui Non Oui Oui 0.9
639 29 Femme Enseignement superieur y compris technique superieur 6145.59325 Exerce une profession Employe 2 Non Rejet Moins important que le reste Equilibre Non Non Non Non Non Oui Non 2.0
640 31 Homme Enseignement superieur y compris technique superieur 5910.77359 Exerce une profession Profession intermediaire 1 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 1.0
641 74 Femme N’a jamais fait d’etudes 3316.89493 Retraite Ouvrier specialise 9 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 3.0
642 20 Femme NA 8301.59157 Etudiant, eleve NA 2 Non Appartenance sans pratique NA NA Non Non Non Oui Non Oui Non 3.0
643 35 Femme 1er cycle 2350.87348 Au foyer Ouvrier qualifie 13 Non Ni croyance ni appartenance NA NA Non Non Non Oui Non Non Non 2.0
644 38 Femme Enseignement superieur y compris technique superieur 8080.76403 Exerce une profession Employe 0 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Non Oui 1.0
645 72 Femme Derniere annee d’etudes primaires 6856.15098 Au foyer NA 9 Non Rejet NA NA Non Non Non Non Non Non Non 2.0
646 18 Homme NA 4545.30523 Exerce une profession Ouvrier specialise 6 Non Ni croyance ni appartenance Moins important que le reste Insatisfaction Non Non Non Non Oui Oui Oui 4.0
647 30 Femme Enseignement superieur y compris technique superieur 850.78965 Exerce une profession Profession intermediaire 5 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Non Oui 2.0
648 51 Homme Enseignement technique ou professionnel long 13115.07945 Exerce une profession Technicien 3 Oui Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Oui Oui Oui Oui 0.3
649 61 Femme Derniere annee d’etudes primaires 9409.97090 Retire des affaires NA 1 Non Pratiquant occasionnel NA NA Non Non Non Oui Oui Non Non 2.0
650 37 Homme Enseignement technique ou professionnel court 2837.36561 Exerce une profession Profession intermediaire 1 Oui Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Oui Oui Oui Oui Oui 2.0
651 30 Femme Enseignement superieur y compris technique superieur 2106.89611 Chomeur Employe 3 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 2.0
652 39 Homme Enseignement technique ou professionnel court 1414.53791 Exerce une profession Ouvrier qualifie 5 Oui Pratiquant occasionnel Aussi important que le reste Equilibre Non Non Non Oui Oui Oui Oui 0.3
653 50 Femme 1er cycle 1285.54567 Exerce une profession NA 6 Non Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Non Non Non Non 0.0
654 56 Femme Derniere annee d’etudes primaires 6368.47979 Au foyer Ouvrier specialise 6 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 2.0
655 66 Femme Derniere annee d’etudes primaires 4165.52267 Retraite Employe 9 Oui Pratiquant regulier NA NA Non Non Non Non Oui Non Non 3.0
656 65 Homme Enseignement technique ou professionnel long 690.80871 Retraite Profession intermediaire 0 Oui Pratiquant regulier NA NA Non Non Non Non Oui Non Non 2.0
657 71 Femme Derniere annee d’etudes primaires 6511.37865 Retraite Ouvrier specialise 4 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 2.0
658 32 Femme 2eme cycle 2820.02739 Exerce une profession Employe 3 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Non Non Oui 1.0
659 78 Homme 1er cycle 5820.34189 Retraite Profession intermediaire 3 Oui Pratiquant occasionnel NA NA Non Non Oui Non Oui Non Oui 3.0
660 25 Femme NA 3223.30320 Exerce une profession Cadre 1 Oui Pratiquant occasionnel Aussi important que le reste Equilibre Non Non Non Oui Non Oui Oui 0.4
661 69 Homme Enseignement technique ou professionnel court 4367.80955 Retraite Profession intermediaire 3 Non Pratiquant occasionnel NA NA Non Non Non Non Oui Oui Oui 2.0
662 30 Homme 1er cycle 17349.28872 Exerce une profession Ouvrier qualifie 4 Non Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Non Non Oui Non Non 0.0
663 66 Femme Enseignement technique ou professionnel court 3588.08192 Retraite Ouvrier qualifie 2 Non Pratiquant occasionnel NA NA Non Non Non Non Non Oui Non 3.0
664 78 Homme Derniere annee d’etudes primaires 14027.77713 Retire des affaires NA 3 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 2.0
665 62 Femme Enseignement technique ou professionnel court 2560.85587 Au foyer Employe 0 Ne sait pas Pratiquant occasionnel NA NA Non Non Non Oui Non Oui Non 4.0
666 45 Femme Enseignement technique ou professionnel court 558.57041 Exerce une profession Employe 2 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Non Non Non 2.0
667 70 Femme Enseignement technique ou professionnel long 7702.86067 Retraite Employe 3 Oui Ni croyance ni appartenance NA NA Non Non Non Oui Non Oui Non 4.0
668 68 Femme Derniere annee d’etudes primaires 1248.87214 Autre inactif NA 1 Oui Pratiquant regulier NA NA Non Non Non Oui Non Non Non 2.0
669 63 Homme 1er cycle 2474.56447 Retraite Employe 0 Non Pratiquant occasionnel NA NA Non Non Non Non Oui Oui Non 2.0
670 75 Homme Enseignement superieur y compris technique superieur 7143.69108 Retraite Cadre 0 Non Appartenance sans pratique NA NA Non Non Non Non Non Oui Oui 0.4
671 35 Femme Enseignement superieur y compris technique superieur 4629.15326 Exerce une profession Profession intermediaire 1 Non Ni croyance ni appartenance Moins important que le reste Insatisfaction Non Non Non Oui Oui Oui Non 0.7
672 31 Femme Enseignement superieur y compris technique superieur 14758.81071 Exerce une profession Cadre 1 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 2.0
673 37 Femme Enseignement superieur y compris technique superieur 1942.18967 Au foyer Cadre 3 Non Ni croyance ni appartenance NA NA Non Non Non Oui Oui Oui Oui 0.4
674 33 Femme 1er cycle 9310.63563 Exerce une profession Ouvrier specialise 3 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Oui Non Non 0.3
675 59 Homme Derniere annee d’etudes primaires 1821.00417 Retraite Ouvrier qualifie 1 Non Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 1.4
676 49 Femme 2eme cycle 4993.05317 Exerce une profession Employe 4 Non Rejet Aussi important que le reste Equilibre Non Non Non Oui Oui Oui Non 0.0
677 70 Homme Derniere annee d’etudes primaires 9553.96929 Retire des affaires NA 1 Oui NSP ou NVPR NA NA Non Non Non Non Non Non Non 3.0
678 56 Femme Enseignement technique ou professionnel court 825.85450 Au foyer Autre 10 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 2.0
679 27 Homme 2eme cycle 7424.20649 Exerce une profession Employe 2 Non NSP ou NVPR Moins important que le reste Satisfaction Non Non Non Non Non Oui Oui 3.0
680 82 Homme Derniere annee d’etudes primaires 3873.80041 Retraite Technicien 3 Oui Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 2.0
681 52 Femme Enseignement superieur y compris technique superieur 4777.51426 Exerce une profession Cadre 3 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Non Oui Oui 1.0
682 64 Homme N’a jamais fait d’etudes 2674.38036 Retraite Ouvrier specialise 2 Non Pratiquant regulier NA NA Non Non Non Non Oui Non Non 2.0
683 43 Homme Enseignement superieur y compris technique superieur 6449.51889 Exerce une profession Profession intermediaire 1 Oui Pratiquant occasionnel Aussi important que le reste Equilibre Non Non Non Oui Oui Oui Oui 1.0
684 77 Homme Derniere annee d’etudes primaires 2318.53573 Retraite Ouvrier qualifie 2 Oui Ni croyance ni appartenance NA NA Non Non Non Oui Oui Non Non 7.0
685 35 Homme Enseignement superieur y compris technique superieur 8733.42835 Exerce une profession Technicien 2 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Non 1.0
686 67 Homme Derniere annee d’etudes primaires 9552.60092 Retraite Ouvrier specialise 4 Non Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 0.0
687 71 Homme Derniere annee d’etudes primaires 9327.73831 Retraite Ouvrier qualifie 5 Oui Pratiquant regulier NA NA Non Non Non Non Oui Non Non 5.0
688 36 Homme 2eme cycle 2853.13449 Exerce une profession Ouvrier qualifie 5 Non NSP ou NVPR Peu important Satisfaction Non Non Non Non Non Oui Non 0.0
689 44 Homme Enseignement technique ou professionnel long 11913.87014 Exerce une profession NA 1 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Non Oui 3.0
690 44 Homme Enseignement technique ou professionnel court 2859.48129 Exerce une profession Employe 4 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Oui Oui 4.0
691 64 Homme Enseignement superieur y compris technique superieur 5934.87245 Retraite Cadre 2 Oui Pratiquant regulier NA NA Non Non Non Non Oui Oui Non 0.7
692 58 Femme Enseignement superieur y compris technique superieur 6715.65990 Exerce une profession Employe 0 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Non 3.0
693 61 Femme 1er cycle 8471.93769 Au foyer Employe 10 Non Pratiquant occasionnel NA NA Non Non Non Oui Oui Non Non 2.0
694 51 Homme Enseignement technique ou professionnel court 6075.33245 Exerce une profession Ouvrier qualifie 3 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Oui Non Oui 0.0
695 61 Homme Enseignement superieur y compris technique superieur 1525.26224 Exerce une profession Cadre 1 Non Rejet Aussi important que le reste Equilibre Non Non Non Non Oui Oui Non 0.0
696 28 Femme 2eme cycle 10333.63278 Au foyer Employe 4 Non Pratiquant occasionnel NA NA Non Non Non Oui Oui Oui Non 2.0
697 64 Homme Derniere annee d’etudes primaires 1632.48564 Retraite Ouvrier specialise 2 Oui Pratiquant occasionnel NA NA Non Non Oui Non Oui Non Non 4.0
698 39 Homme Enseignement technique ou professionnel court 2063.86037 Exerce une profession NA 3 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Oui Non 0.0
699 42 Femme Enseignement technique ou professionnel long 768.76526 Au foyer Employe 6 Non Ni croyance ni appartenance NA NA Non Non Non Oui Non Oui Oui 0.9
700 55 Homme 2eme cycle 5933.35310 Exerce une profession Cadre 4 Oui Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Non Oui Oui Oui Non 0.1
701 65 Homme Enseignement technique ou professionnel long 9046.53398 Retraite Cadre 1 Oui Appartenance sans pratique NA NA Non Non Non Oui Oui Non Oui 4.0
702 77 Femme N’a jamais fait d’etudes 2564.21200 Retraite Ouvrier specialise 5 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 2.0
703 24 Homme Enseignement superieur y compris technique superieur 3840.48642 Exerce une profession Technicien 2 Non Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Oui Oui Oui Oui 1.0
704 21 Homme NA 10820.50295 Etudiant, eleve NA 4 Oui Pratiquant regulier NA NA Non Non Non Oui Oui Oui Oui 1.0
705 47 Femme Enseignement superieur y compris technique superieur 5326.74244 Exerce une profession Cadre 2 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 2.0
706 67 Femme Derniere annee d’etudes primaires 1280.24825 Retraite Employe 6 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Non Oui 0.0
707 36 Homme 2eme cycle 2289.32303 Exerce une profession Employe 0 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Oui Oui 4.0
708 61 Homme Derniere annee d’etudes primaires 5367.66973 Retraite Ouvrier qualifie 12 Non Pratiquant occasionnel NA NA Non Non Oui Oui Oui Non Non 3.0
709 63 Homme Derniere annee d’etudes primaires 6287.49937 Retraite Ouvrier qualifie 5 Non Ni croyance ni appartenance NA NA Non Non Non Non Oui Non Oui 4.0
710 49 Femme 2eme cycle 7151.68483 Exerce une profession Profession intermediaire 1 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Non Oui Non 1.0
711 29 Femme Enseignement technique ou professionnel court 320.58075 Exerce une profession Employe 8 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Non Non Non 3.0
712 58 Femme Enseignement superieur y compris technique superieur 2491.48956 Exerce une profession Cadre 2 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 0.0
713 52 Homme Enseignement technique ou professionnel court 1658.83021 Exerce une profession Employe 7 Non Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Oui Non Oui Non Oui 1.0
714 31 Femme Enseignement technique ou professionnel court 8553.42734 Au foyer Employe 2 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Oui 3.0
715 38 Homme Enseignement superieur y compris technique superieur 5581.69371 Exerce une profession Cadre 7 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Oui Non 2.0
716 58 Femme Enseignement technique ou professionnel court 1009.89614 Exerce une profession Profession intermediaire 5 Non Ni croyance ni appartenance Moins important que le reste Insatisfaction Non Non Non Non Oui Non Non 1.0
717 50 Homme Derniere annee d’etudes primaires 9837.49616 Exerce une profession NA 1 Non Ni croyance ni appartenance Aussi important que le reste Insatisfaction Non Non Non Non Non Non Non 4.0
718 40 Femme 2eme cycle 5458.15981 Exerce une profession Profession intermediaire 1 Oui Ni croyance ni appartenance Moins important que le reste Insatisfaction Non Non Non Oui Oui Non Oui 3.0
719 60 Femme Enseignement superieur y compris technique superieur 5116.91073 Exerce une profession Cadre 4 Non Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Non Non Oui Non 0.0
720 55 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 14946.79966 Exerce une profession Ouvrier qualifie 13 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Non Non Non 3.0
721 43 Homme 1er cycle 12761.47192 Exerce une profession Ouvrier qualifie 1 Oui Appartenance sans pratique Aussi important que le reste Insatisfaction Non Non Non Non Oui Oui Oui 0.0
722 28 Femme Enseignement superieur y compris technique superieur 7147.28264 Exerce une profession Employe 2 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 0.0
723 59 Homme Enseignement superieur y compris technique superieur 772.09029 Exerce une profession Cadre 2 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Non Non Oui 1.0
724 35 Homme Enseignement technique ou professionnel court 1334.97342 Exerce une profession Ouvrier qualifie 5 Oui Pratiquant occasionnel Aussi important que le reste Insatisfaction Non Non Non Non Oui Non Oui 1.0
725 53 Homme 2eme cycle 9837.49616 Exerce une profession NA 1 Oui Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Non Non Non Non 2.0
726 19 Homme NA 3439.00971 Etudiant, eleve NA 3 Non Appartenance sans pratique NA NA Non Non Non Non Non Oui Oui 2.0
727 39 Femme Enseignement technique ou professionnel court 1008.92675 Chomeur Employe 4 Oui Pratiquant regulier NA NA Non Non Non Oui Non Non Non 0.0
728 41 Femme 2eme cycle 5500.62645 Exerce une profession Ouvrier specialise 4 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Non Non Oui 3.0
729 32 Homme Enseignement superieur y compris technique superieur 5544.51375 Exerce une profession Cadre 0 Non Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Oui Oui Non Non 2.0
730 45 Homme Derniere annee d’etudes primaires 3421.95972 Exerce une profession Ouvrier qualifie 6 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Oui Oui Non Non Non 0.0
731 64 Homme Derniere annee d’etudes primaires 1364.04350 Retraite Employe 2 Oui Pratiquant occasionnel NA NA Non Non Oui Oui Non Non Non 1.0
732 45 Femme 1er cycle 2381.25706 Exerce une profession Employe 3 Oui Appartenance sans pratique Peu important Satisfaction Non Non Non Oui Non Non Non 0.0
733 40 Femme 1er cycle 433.32346 Exerce une profession Employe 7 Non Pratiquant regulier Peu important Equilibre Non Non Non Oui Non Oui Non 0.4
734 73 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 13580.64222 Retraite Ouvrier specialise 3 Non Appartenance sans pratique NA NA Non Non Oui Non Non Non Non 4.0
735 47 Femme 2eme cycle 1869.67379 Exerce une profession Autre 4 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Oui Non Non 1.0
736 59 Femme Derniere annee d’etudes primaires 5014.31571 Au foyer Employe 5 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 2.0
737 41 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 1226.35758 Exerce une profession Employe 9 Non Pratiquant regulier Aussi important que le reste Equilibre Non Non Non Non Non Non Non 5.0
738 61 Femme Derniere annee d’etudes primaires 7239.40283 Retraite Ouvrier specialise 5 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 4.0
739 35 Homme Enseignement superieur y compris technique superieur 7523.98480 Exerce une profession Profession intermediaire 2 Oui Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Oui Oui Oui Oui Oui 0.0
740 54 Femme Derniere annee d’etudes primaires 2873.10451 Au foyer NA 3 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 2.0
741 29 Homme Enseignement technique ou professionnel long 7996.01057 Exerce une profession Profession intermediaire 1 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Oui Oui Oui 1.0
742 73 Femme Derniere annee d’etudes primaires 1080.37162 Retraite NA 1 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 4.0
743 47 Homme Enseignement superieur y compris technique superieur 10606.69164 Exerce une profession Cadre 3 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Non 3.0
744 21 Homme Enseignement technique ou professionnel long 10239.32256 Etudiant, eleve NA 1 Oui Rejet NA NA Non Non Non Non Non Oui Non 0.0
745 48 Homme Derniere annee d’etudes primaires 1025.78251 Exerce une profession Ouvrier specialise 9 Non Pratiquant occasionnel Aussi important que le reste Equilibre Non Non Non Non Non Non Oui 1.0
746 49 Femme Enseignement technique ou professionnel court 3687.97811 Au foyer Cadre 3 Oui Pratiquant regulier NA NA Non Non Oui Oui Non Oui Oui 0.3
747 59 Homme Enseignement superieur y compris technique superieur 883.34941 Exerce une profession Cadre 3 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Oui Oui 1.1
748 31 Homme Enseignement technique ou professionnel court 9050.24521 Exerce une profession Ouvrier qualifie 1 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 5.0
749 77 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 3200.67203 Autre inactif Ouvrier qualifie 3 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 4.0
750 48 Femme Derniere annee d’etudes primaires 8157.20434 Au foyer NA 11 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 2.0
751 37 Femme Enseignement technique ou professionnel long 1086.59011 Chomeur Ouvrier specialise 8 Ne sait pas Pratiquant regulier NA NA Non Non Non Oui Non Non Non 3.0
752 28 Homme 1er cycle 16570.12070 Exerce une profession Ouvrier specialise 4 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Non Oui Non 3.0
753 47 Femme 2eme cycle 4269.16065 Exerce une profession Employe 4 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Non Non 3.0
754 82 Femme 2eme cycle 6969.16902 Retraite Employe 0 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 1.0
755 31 Homme Enseignement technique ou professionnel long 10332.16009 Exerce une profession NA 1 Oui Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Non Oui Non Non 2.0
756 33 Femme NA 5133.69570 Exerce une profession Autre 2 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Oui Non Oui 1.0
757 30 Femme Enseignement superieur y compris technique superieur 2179.90972 Exerce une profession Employe 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Non 2.0
758 47 Homme Enseignement technique ou professionnel court 2485.52436 Exerce une profession NA 1 Non Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Oui Non Oui Non 1.0
759 89 Femme Derniere annee d’etudes primaires 9554.68018 Au foyer NA 1 Non Pratiquant regulier NA NA Non Non Non Non Non Non Oui 3.0
760 61 Femme Derniere annee d’etudes primaires 8093.42129 Retire des affaires NA 3 Oui Pratiquant regulier NA NA Non Non Non Non Oui Oui Oui 3.0
761 78 Femme Derniere annee d’etudes primaires 2175.57369 Retraite Ouvrier qualifie 7 Non Appartenance sans pratique NA NA Non Non Non Oui Oui Non Non 3.0
762 43 Femme Enseignement technique ou professionnel court 6992.74554 Exerce une profession Ouvrier specialise 10 Non Ni croyance ni appartenance Moins important que le reste Insatisfaction Non Non Non Non Non Non Oui 2.0
763 73 Homme 1er cycle 1027.22952 Retraite Ouvrier qualifie 2 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 1.0
764 26 Femme Enseignement superieur y compris technique superieur 9990.39519 Au foyer NA 7 Oui Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 3.0
765 58 Homme Enseignement technique ou professionnel court 7524.60411 Exerce une profession Technicien 4 Oui Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Non Oui Non Non 2.0
766 32 Femme Enseignement superieur y compris technique superieur 6864.51073 Exerce une profession Cadre 1 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Non Oui Oui 0.7
767 30 Femme Derniere annee d’etudes primaires 18709.69268 Au foyer Employe 2 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 1.0
768 60 Homme 1er cycle 2579.20321 Retraite Cadre 0 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 8.0
769 36 Femme Enseignement superieur y compris technique superieur 11715.02569 Exerce une profession NA 8 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Non Oui Oui 0.0
770 44 Homme Enseignement technique ou professionnel court 6040.17173 Exerce une profession Ouvrier qualifie 4 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 3.0
771 22 Femme NA 7128.36274 Etudiant, eleve NA 1 Non Rejet NA NA Non Non Non Non Non Oui Non 2.0
772 25 Femme Enseignement superieur y compris technique superieur 10859.18982 Exerce une profession Cadre 2 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 2.0
773 56 Femme Derniere annee d’etudes primaires 5389.36524 Exerce une profession Employe 6 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Oui Non Non 3.0
774 63 Femme 1er cycle 3777.25682 Retraite Employe 3 Oui Appartenance sans pratique NA NA Non Non Non Oui Oui Oui Oui 2.0
775 74 Femme Derniere annee d’etudes primaires 9115.16425 Retire des affaires NA 4 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 6.0
776 61 Homme 1er cycle 1264.93006 Retraite Ouvrier qualifie 2 Oui Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 0.0
777 56 Homme Enseignement technique ou professionnel court 5217.08228 Exerce une profession Cadre 4 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Oui Non Oui Non Non 2.0
778 48 Homme Enseignement technique ou professionnel long 4670.87574 Exerce une profession Profession intermediaire 1 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Oui Oui Oui 3.0
779 62 Femme 2eme cycle 2720.58113 Retraite Employe 0 Oui Appartenance sans pratique NA NA Non Non Non Oui Oui Non Non 4.0
780 36 Femme NA 2887.95673 Exerce une profession Employe 9 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Non Non Oui 0.0
781 64 Femme Derniere annee d’etudes primaires 3242.02937 Retraite Employe 3 Oui Ni croyance ni appartenance NA NA Non Non Non Oui Non Oui Non 5.0
782 57 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 261.71764 Au foyer Employe 1 Non Pratiquant regulier NA NA Non Non Non Non Oui Non Non 3.0
783 42 Femme Enseignement technique ou professionnel court 10302.99602 Exerce une profession Ouvrier qualifie 4 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Non Non 0.4
784 30 Homme Enseignement superieur y compris technique superieur 8316.77062 Exerce une profession Technicien 0 Oui Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Oui Oui Oui Non Oui 2.0
785 45 Homme Enseignement technique ou professionnel court 12379.09374 Exerce une profession NA 2 Non Pratiquant occasionnel Aussi important que le reste Equilibre Non Non Non Non Oui Non Non 2.0
786 25 Homme Enseignement technique ou professionnel court 13607.53840 Exerce une profession Employe 0 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Oui Non Oui Oui Oui 1.4
787 55 Femme Enseignement technique ou professionnel court 4928.43427 Exerce une profession Employe 1 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Non Non 3.0
788 45 Homme Enseignement superieur y compris technique superieur 10393.37503 Exerce une profession Profession intermediaire 5 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 2.0
789 44 Homme Enseignement superieur y compris technique superieur 3105.11127 Exerce une profession Profession intermediaire 4 Non Rejet Peu important Equilibre Oui Non Oui Non Non Oui Non 2.0
790 53 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 3241.44390 Exerce une profession Ouvrier qualifie 4 Non Pratiquant regulier Aussi important que le reste Equilibre Non Non Non Non Non Non Non 1.0
791 52 Femme N’a jamais fait d’etudes 2631.21743 Chomeur Ouvrier specialise 12 Oui Pratiquant regulier NA NA Non Non Non Oui Non Oui Non 5.0
792 34 Femme Enseignement technique ou professionnel court 4049.14489 Exerce une profession Employe 1 Oui Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Non Oui Oui Non 3.0
793 53 Femme Derniere annee d’etudes primaires 11530.57122 Au foyer Ouvrier specialise 8 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 5.0
794 25 Femme Enseignement technique ou professionnel long 15044.27884 Exerce une profession Employe 4 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Non Oui Non 0.0
795 73 Femme Derniere annee d’etudes primaires 7166.74262 Retraite Ouvrier qualifie 7 Oui Pratiquant regulier NA NA Non Non Non Oui Non Non Non 3.0
796 75 Homme Derniere annee d’etudes primaires 3862.05988 Retraite Ouvrier qualifie 4 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 3.0
797 47 Femme Enseignement technique ou professionnel court 4692.16527 Exerce une profession Employe 2 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Non Non 4.0
798 60 Femme Enseignement technique ou professionnel long 5294.66782 Au foyer Autre 3 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 0.0
799 29 Femme Enseignement technique ou professionnel court 6790.53513 Chomeur Ouvrier qualifie 3 Non Appartenance sans pratique NA NA Non Non Non Oui Oui Oui Non 3.0
800 43 Homme Enseignement technique ou professionnel court 625.21998 Chomeur Ouvrier qualifie 1 Oui Appartenance sans pratique NA NA Non Non Oui Oui Oui Non Non 2.0
801 42 Homme Enseignement technique ou professionnel court 4084.46759 Exerce une profession Ouvrier specialise 3 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Oui Non Oui Non Non 3.0
802 48 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 1180.98570 Retraite Ouvrier specialise 5 Non Pratiquant regulier NA NA Non Non Non Non Oui Non Non 0.0
803 59 Femme N’a jamais fait d’etudes 968.01988 Exerce une profession Ouvrier specialise 6 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Non Non Non 7.0
804 72 Femme Derniere annee d’etudes primaires 8585.31073 Retraite Ouvrier qualifie 2 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 0.3
805 47 Femme 1er cycle 6328.48895 Exerce une profession Employe 1 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Oui Non Non 0.1
806 52 Femme Derniere annee d’etudes primaires 1091.92665 Exerce une profession Autre 2 Non Pratiquant regulier Moins important que le reste Equilibre Non Non Non Oui Non Non Non 0.0
807 51 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 8229.21578 Retraite Ouvrier specialise 4 Non Pratiquant regulier NA NA Non Non Non Non Oui Non Non 0.0
808 30 Femme Enseignement superieur y compris technique superieur 7047.88027 Au foyer Cadre 4 Oui Pratiquant regulier NA NA Non Non Oui Oui Oui Oui Oui 2.0
809 32 Femme Enseignement superieur y compris technique superieur 3628.06951 Exerce une profession Cadre 3 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Non Oui Oui 1.0
810 53 Femme Enseignement technique ou professionnel court 1359.00480 Exerce une profession NA 0 Non Appartenance sans pratique Le plus important Equilibre Non Non Non Non Non Oui Oui 2.0
811 55 Homme Enseignement technique ou professionnel court 1309.29374 Chomeur Ouvrier qualifie 4 Oui NSP ou NVPR NA NA Non Non Oui Non Non Non Non 3.0
812 82 Femme Enseignement superieur y compris technique superieur 15383.01454 Retraite Cadre 1 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 0.0
813 56 Femme Derniere annee d’etudes primaires 1464.55371 Au foyer Ouvrier specialise 2 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 4.0
814 63 Homme Derniere annee d’etudes primaires 262.69840 Retraite Profession intermediaire 1 Non Ni croyance ni appartenance NA NA Non Non Non Non Oui Non Non 3.0
815 46 Femme Enseignement technique ou professionnel court 4443.34360 Chomeur Ouvrier qualifie 2 Oui Pratiquant occasionnel NA NA Non Non Non Oui Oui Non Non 2.0
816 65 Femme Enseignement technique ou professionnel court 7338.87550 Exerce une profession NA 4 Oui Appartenance sans pratique Le plus important Satisfaction Non Non Non Non Oui Oui Non 1.0
817 37 Homme Enseignement technique ou professionnel court 7417.56071 Exerce une profession NA 3 Oui Rejet Aussi important que le reste Equilibre Non Non Non Non Oui Oui Non 0.0
818 53 Homme Enseignement technique ou professionnel court 29657.94035 Exerce une profession Technicien 4 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Oui Non Oui Oui Non 3.0
819 67 Femme Derniere annee d’etudes primaires 8744.29485 Retraite Employe 5 Ne sait pas Appartenance sans pratique NA NA Non Non Oui Oui Non Non Oui 3.0
820 45 Homme Enseignement technique ou professionnel court 1192.89354 Exerce une profession Ouvrier qualifie 2 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Non Non Non 2.0
821 51 Femme Derniere annee d’etudes primaires 646.40013 Exerce une profession Employe 6 Oui Pratiquant occasionnel Moins important que le reste Insatisfaction Non Non Non Non Non Oui Non 3.0
822 52 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 5262.43486 Chomeur Employe 4 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 1.0
823 33 Homme Enseignement technique ou professionnel long 1071.98313 Exerce une profession Ouvrier qualifie 1 Oui Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Non Oui Oui Non 4.0
824 39 Homme Enseignement superieur y compris technique superieur 7906.42398 Exerce une profession Profession intermediaire 2 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Oui Non Non 3.0
825 57 Femme 2eme cycle 6589.42134 Exerce une profession NA 1 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Non Non 4.0
826 20 Femme NA 3564.18137 Etudiant, eleve NA 1 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 0.4
827 58 Femme 1er cycle 1164.61797 Autre inactif Employe 6 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 3.0
828 28 Femme Enseignement technique ou professionnel long 13720.73546 Exerce une profession NA 0 Non Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Non Non Oui Oui Oui 1.0
829 38 Femme Enseignement technique ou professionnel long 7451.68794 Exerce une profession NA 1 Oui Pratiquant regulier Moins important que le reste Equilibre Non Non Non Non Oui Non Non 2.0
830 67 Homme 1er cycle 3447.44381 Retire des affaires NA 1 Non Pratiquant occasionnel NA NA Non Non Oui Oui Oui Non Non 2.0
831 28 Femme Enseignement superieur y compris technique superieur 7147.28264 Exerce une profession Profession intermediaire 8 Oui Pratiquant occasionnel Aussi important que le reste Equilibre Non Non Non Oui Oui Oui Oui 0.4
832 51 Homme Enseignement technique ou professionnel court 9721.73309 Exerce une profession Technicien 6 Oui Pratiquant occasionnel Aussi important que le reste Equilibre Non Non Oui Non Oui Non Oui 1.0
833 49 Homme Enseignement technique ou professionnel long 1393.90271 Exerce une profession Cadre 1 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Oui Non 1.1
834 76 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 2335.64016 Retraite NA 4 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 0.0
835 50 Homme Enseignement superieur y compris technique superieur 7966.27380 Exerce une profession Cadre 1 Oui Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Non Non Non Oui Non 0.0
836 54 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 1943.01198 Exerce une profession NA 11 Non Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Non Non Non Non Non 1.0
837 75 Homme Derniere annee d’etudes primaires 6007.19291 Retraite Autre 7 Non Pratiquant occasionnel NA NA Non Non Oui Non Non Non Non 0.0
838 59 Homme Derniere annee d’etudes primaires 4200.52976 Retraite Ouvrier qualifie 2 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Non Oui 5.0
839 79 Femme Derniere annee d’etudes primaires 4277.58001 Retire des affaires NA 4 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 4.0
840 27 Homme Enseignement technique ou professionnel long 2283.09457 Exerce une profession NA 2 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Oui 0.6
841 48 Femme Derniere annee d’etudes primaires 1757.05680 Autre inactif Employe 5 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 10.0
842 53 Femme Enseignement superieur y compris technique superieur 487.69663 Exerce une profession Cadre 0 Oui Pratiquant regulier Moins important que le reste Satisfaction Non Non Oui Oui Non Oui Non 2.0
843 30 Homme Enseignement superieur y compris technique superieur 5731.66151 Exerce une profession Ouvrier qualifie 3 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 1.0
844 36 Homme 1er cycle 2030.52706 Exerce une profession Employe 4 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Non Non 5.0
845 30 Homme Enseignement technique ou professionnel court 1940.37518 Exerce une profession Ouvrier qualifie 1 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Non Non Oui 4.0
846 35 Homme Enseignement superieur y compris technique superieur 8274.19316 Chomeur Employe 7 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Oui Oui 3.0
847 47 Femme Enseignement technique ou professionnel court 1420.37273 Exerce une profession Employe 3 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 0.0
848 34 Femme Enseignement superieur y compris technique superieur 5513.76263 Exerce une profession Employe 2 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Oui Non Non 3.0
849 49 Homme 1er cycle 8031.36210 Exerce une profession Ouvrier qualifie 4 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Oui Non 0.4
850 78 Homme Enseignement technique ou professionnel court 3176.39477 Retraite Employe 3 Non Ni croyance ni appartenance NA NA Non Non Non Non Oui Non Non 2.0
851 39 Femme Enseignement superieur y compris technique superieur 6178.42919 Autre inactif Employe 2 Non Ni croyance ni appartenance NA NA Non Oui Non Oui Oui Non Non 1.0
852 18 Femme NA 3284.63877 Etudiant, eleve NA 0 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Oui Oui 0.1
853 42 Homme Enseignement technique ou professionnel long 521.34264 Exerce une profession Profession intermediaire 3 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Oui Oui Oui Non Non 2.0
854 33 Homme 1er cycle 6978.11309 Exerce une profession Ouvrier qualifie 2 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Non Non Non 4.3
855 22 Femme NA 3564.18137 Etudiant, eleve NA 1 Oui Ni croyance ni appartenance NA NA Non Non Non Oui Oui Oui Oui 1.0
856 40 Homme 2eme cycle 7916.67722 Exerce une profession Cadre 1 Oui Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Non Oui Oui Oui 2.0
857 42 Femme Enseignement superieur y compris technique superieur 2420.83948 Exerce une profession Profession intermediaire 7 Non Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Non Non Non Non 1.0
858 26 Homme Enseignement technique ou professionnel court 8882.49835 Exerce une profession Ouvrier specialise 1 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Oui Non Non 3.0
859 51 Homme Enseignement superieur y compris technique superieur 5390.87477 Exerce une profession Profession intermediaire 1 Oui Pratiquant occasionnel Moins important que le reste Insatisfaction Non Non Non Non Non Oui Non 2.0
860 77 Femme Derniere annee d’etudes primaires 6523.79481 Retire des affaires NA 5 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 2.0
861 38 Femme Enseignement superieur y compris technique superieur 2838.17377 Exerce une profession Employe 1 Non Rejet Moins important que le reste Equilibre Non Non Non Oui Non Oui Oui 2.0
862 37 Homme Enseignement superieur y compris technique superieur 2567.57328 Exerce une profession Profession intermediaire 11 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 1.1
863 54 Femme 2eme cycle 6495.10090 Exerce une profession Ouvrier qualifie 3 Oui Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Oui Oui Oui Non 0.4
864 87 Homme Derniere annee d’etudes primaires 1019.15644 Retraite Ouvrier qualifie 0 Oui Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 4.0
865 70 Homme Enseignement technique ou professionnel long 1439.62914 Retraite Autre 0 Non Pratiquant regulier NA NA Non Non Non Non Oui Non Non 0.0
866 56 Homme 1er cycle 1986.11464 Exerce une profession Ouvrier qualifie 0 Non Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Oui Oui Non Oui 2.0
867 59 Femme 1er cycle 3033.57695 Retraite Employe 7 Oui Rejet NA NA Non Non Non Oui Oui Non Non 2.0
868 30 Homme Enseignement technique ou professionnel long 5571.39890 Chomeur Technicien 2 Non Ni croyance ni appartenance NA NA Non Non Non Oui Oui Oui Non 3.0
869 36 Femme 1er cycle 5276.09400 Exerce une profession Ouvrier qualifie 10 Ne sait pas Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Non Non Non 1.0
870 82 Homme Derniere annee d’etudes primaires 2278.99927 Retraite Ouvrier qualifie 1 Oui Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 4.0
871 60 Homme 2eme cycle 305.44793 Retraite Ouvrier specialise 2 Non Rejet NA NA Non Non Non Non Oui Non Oui 4.0
872 33 Femme Enseignement superieur y compris technique superieur 5513.76263 Exerce une profession Autre 2 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Oui Oui Non 0.4
873 77 Homme Enseignement superieur y compris technique superieur 12933.41265 Retraite Cadre 0 Oui Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 1.0
874 75 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 3005.34500 Retraite Ouvrier specialise 4 Non Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 5.0
875 52 Homme Derniere annee d’etudes primaires 1259.57638 Exerce une profession Ouvrier specialise 5 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Oui Oui Non 5.0
876 41 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 302.29352 Chomeur Employe 4 Non Pratiquant occasionnel NA NA Non Non Non Non Non Oui Non 1.0
877 67 Femme Enseignement technique ou professionnel court 6200.97477 Retraite Cadre 6 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 3.0
878 58 Femme Derniere annee d’etudes primaires 3885.26104 Retraite Ouvrier qualifie 4 Oui Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 0.0
879 71 Homme 1er cycle 1347.90418 Autre inactif NA 5 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 0.0
880 32 Homme Enseignement superieur y compris technique superieur 1731.26116 Exerce une profession Employe 1 Oui Appartenance sans pratique Moins important que le reste Satisfaction Oui Non Non Oui Non Oui Oui 2.0
881 78 Femme 1er cycle 1111.52211 Retraite Employe 1 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 3.0
882 31 Femme Enseignement technique ou professionnel court 8750.76665 Exerce une profession Employe 3 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Non Non Oui 2.0
883 72 Homme Derniere annee d’etudes primaires 2771.07574 Retire des affaires NA 12 Oui Pratiquant regulier NA NA Non Non Non Oui Oui Non Non 2.0
884 51 Homme Enseignement superieur y compris technique superieur 17547.49437 Exerce une profession Cadre 2 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Non Non Oui 1.0
885 22 Homme NA 10312.67934 Etudiant, eleve NA 3 Non Ni croyance ni appartenance NA NA Non Non Non Oui Non Oui Non 0.0
886 45 Homme Enseignement technique ou professionnel court 6721.53253 Exerce une profession Ouvrier qualifie 5 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Oui Non Non 2.0
887 42 Homme Enseignement technique ou professionnel court 13566.87326 Exerce une profession Ouvrier qualifie 1 Oui Rejet Moins important que le reste Equilibre Non Non Non Oui Oui Oui Non 4.0
888 25 Homme Enseignement technique ou professionnel court 9292.97620 Exerce une profession Technicien 1 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Non Non 0.0
889 39 Homme 2eme cycle 3899.63101 Exerce une profession Ouvrier specialise 5 Oui Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Oui Oui Oui Oui 2.0
890 71 Femme N’a jamais fait d’etudes 2114.79233 Au foyer NA 7 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 1.0
891 77 Homme 1er cycle 4836.57847 Retraite Employe 6 Non Pratiquant regulier NA NA Non Non Non Non Non Oui Non 0.0
892 41 Homme Enseignement superieur y compris technique superieur 880.62721 Exerce une profession Cadre 1 Non Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Non Non Oui Oui Non 2.0
893 38 Homme Enseignement technique ou professionnel court 8911.37123 Exerce une profession Ouvrier qualifie 4 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Non Non Non 0.0
894 39 Homme 1er cycle 11811.40033 Exerce une profession NA 4 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Oui Non Oui Non Oui 0.0
895 54 Homme Derniere annee d’etudes primaires 3018.57943 Exerce une profession Ouvrier qualifie 5 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Oui Non Non 0.1
896 51 Femme 2eme cycle 2486.07971 Exerce une profession Employe 1 Oui Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Non Non Non Non 2.0
897 44 Femme 1er cycle 1805.21361 Exerce une profession Employe 13 Oui Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Non 1.0
898 27 Homme Enseignement superieur y compris technique superieur 13839.11640 Exerce une profession Cadre 2 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 0.7
899 22 Femme NA 3564.18137 Etudiant, eleve NA 1 Non Pratiquant occasionnel NA NA Non Non Non Oui Oui Oui Oui 2.0
900 33 Femme 2eme cycle 5645.69969 Exerce une profession Cadre 1 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 2.0
901 70 Femme N’a jamais fait d’etudes 1808.44613 Au foyer NA 6 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 3.0
902 43 Homme Enseignement technique ou professionnel court 3229.74425 Exerce une profession Ouvrier qualifie 6 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Oui Oui 5.0
903 26 Homme Enseignement superieur y compris technique superieur 8659.04803 Exerce une profession Employe 1 Oui Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Oui Oui Non Oui Oui 3.0
904 27 Femme Enseignement superieur y compris technique superieur 4302.71127 Exerce une profession Cadre 1 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Non Oui Non 0.3
905 26 Homme Enseignement superieur y compris technique superieur 10637.42813 Exerce une profession Ouvrier qualifie 2 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Oui Non Non Oui Oui 1.0
906 22 Femme NA 1654.59924 Etudiant, eleve NA 1 Non Ni croyance ni appartenance NA NA Non Non Non Oui Non Oui Oui 0.3
907 56 Homme Enseignement superieur y compris technique superieur 3547.84777 Exerce une profession Cadre 7 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 1.0
908 25 Femme NA 7785.06046 Etudiant, eleve NA 3 Oui Appartenance sans pratique NA NA Oui Non Oui Oui Non Oui Non 5.1
909 64 Femme Enseignement superieur y compris technique superieur 7298.09708 Retraite Cadre 8 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Oui Non 2.0
910 77 Homme Enseignement technique ou professionnel court 4683.76662 Retraite Technicien 1 Non Pratiquant regulier NA NA Non Non Non Non Oui Non Non 3.0
911 36 Femme Enseignement superieur y compris technique superieur 6692.52784 Au foyer Ouvrier specialise 3 Oui Appartenance sans pratique NA NA Non Non Oui Oui Oui Non Non 2.0
912 36 Femme Enseignement technique ou professionnel court 8468.54954 Exerce une profession Employe 3 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Non Oui 0.4
913 44 Homme Enseignement technique ou professionnel court 7917.13155 Exerce une profession Ouvrier qualifie 2 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Oui Non Non Non Oui 3.0
914 72 Femme Derniere annee d’etudes primaires 1101.78846 Retraite NA 3 Oui Pratiquant occasionnel NA NA Non Non Oui Oui Non Non Non 2.0
915 56 Homme 1er cycle 3175.27421 Exerce une profession Employe 1 Oui Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Non Oui Non Non 0.6
916 18 Femme NA 3564.18137 Etudiant, eleve NA 2 Non Ni croyance ni appartenance NA NA Non Non Oui Non Oui Oui Oui 0.1
917 44 Homme 1er cycle 3645.11182 Exerce une profession NA 6 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Oui Non Non 0.4
918 88 Homme Derniere annee d’etudes primaires 8427.06810 Retire des affaires NA 10 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 4.0
919 34 Homme 2eme cycle 3898.90905 Exerce une profession NA 2 Oui Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Oui Non Non Non Non 3.0
920 42 Femme Enseignement technique ou professionnel court 5005.94165 Chomeur Ouvrier qualifie 2 Non Pratiquant occasionnel NA NA Non Non Oui Oui Non Oui Non 2.0
921 36 Femme Enseignement technique ou professionnel court 1684.17580 Exerce une profession Employe 8 Non Pratiquant regulier Moins important que le reste Equilibre Non Non Non Non Non Non Oui 2.0
922 20 Homme NA 14798.83394 Etudiant, eleve NA 1 Non Ni croyance ni appartenance NA NA Non Non Non Oui Non Oui Oui 0.2
923 45 Femme Enseignement superieur y compris technique superieur 6328.48895 Exerce une profession Cadre 2 Oui Pratiquant regulier Aussi important que le reste Equilibre Non Oui Non Oui Oui Oui Oui 2.0
924 30 Homme Enseignement superieur y compris technique superieur 4990.42203 Chomeur NA 2 Non Ni croyance ni appartenance NA NA Non Non Oui Non Oui Non Oui 1.0
925 69 Femme Enseignement technique ou professionnel court 9437.98113 Retraite NA 3 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 3.0
926 30 Femme Enseignement technique ou professionnel long 688.57688 Exerce une profession Employe 0 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Non Non Non 2.0
927 41 Femme Enseignement technique ou professionnel court 3759.14900 Exerce une profession Profession intermediaire 3 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Oui Oui 2.0
928 36 Femme Enseignement superieur y compris technique superieur 1540.80834 Exerce une profession Cadre 2 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Non 1.0
929 50 Homme Enseignement superieur y compris technique superieur 5662.78790 Exerce une profession Cadre 1 Oui Ni croyance ni appartenance Peu important Satisfaction Non Non Non Non Oui Oui Non 0.1
930 23 Femme 2eme cycle 8324.60479 Au foyer Employe 7 Ne sait pas Pratiquant occasionnel NA NA Non Non Non Non Oui Oui Non 3.0
931 52 Femme Enseignement superieur y compris technique superieur 2652.78401 Exerce une profession Cadre 3 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Non Oui 1.0
932 71 Femme Derniere annee d’etudes primaires 2125.67730 Retire des affaires NA 1 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 0.0
933 50 Femme Enseignement superieur y compris technique superieur 3765.65249 Exerce une profession Cadre 1 Non Rejet Moins important que le reste Satisfaction Non Oui Non Non Non Oui Non 1.0
934 69 Homme 2eme cycle 5376.16490 Retraite Cadre 4 Oui Appartenance sans pratique NA NA Non Non Oui Non Oui Non Oui 2.0
935 77 Homme Derniere annee d’etudes primaires 13140.92970 Retire des affaires NA 3 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 5.0
936 55 Femme Enseignement technique ou professionnel court 2263.05288 Exerce une profession Employe 4 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Oui Non Oui 2.0
937 70 Femme Derniere annee d’etudes primaires 871.71047 Autre inactif Profession intermediaire 2 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 0.0
938 29 Homme Enseignement technique ou professionnel court 4547.19807 Chomeur Ouvrier specialise 7 Non Ni croyance ni appartenance NA NA Non Non Oui Oui Non Non Oui NA
939 23 Femme Enseignement superieur y compris technique superieur 31092.14132 Exerce une profession Profession intermediaire 2 Oui Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 0.0
940 63 Femme Derniere annee d’etudes primaires 3646.02470 Chomeur Employe 8 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 0.4
941 69 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 2484.52919 Retraite Employe 10 Oui Pratiquant occasionnel NA NA Non Non Non Oui Oui Non Non 1.0
942 72 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 14727.67635 Retire des affaires NA 2 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 4.0
943 36 Femme Enseignement superieur y compris technique superieur 1870.56368 Exerce une profession Profession intermediaire 1 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Non 2.0
944 53 Femme Derniere annee d’etudes primaires 2426.06778 Autre inactif Employe 4 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 6.0
945 34 Femme 1er cycle 1246.88502 Chomeur Employe 3 Oui Pratiquant regulier NA NA Non Non Non Oui Non Non Non 3.0
946 46 Femme Enseignement superieur y compris technique superieur 2368.23853 Exerce une profession Profession intermediaire 7 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Oui Non Oui 0.6
947 54 Femme Enseignement superieur y compris technique superieur 5065.40059 Au foyer NA 4 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Oui Oui 1.0
948 78 Femme Derniere annee d’etudes primaires 7975.21857 Retraite Ouvrier specialise 3 Oui Pratiquant regulier NA NA Non Non Non Oui Non Non Non 1.0
949 46 Femme Derniere annee d’etudes primaires 3288.10310 Au foyer Ouvrier specialise 6 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 4.0
950 64 Homme Enseignement technique ou professionnel court 3204.50711 Retraite Employe 4 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 8.0
951 42 Femme Enseignement superieur y compris technique superieur 3446.19259 Exerce une profession NA 2 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Oui Oui 0.4
952 63 Homme Derniere annee d’etudes primaires 1161.82293 Chomeur Ouvrier specialise 8 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 6.0
953 47 Femme Enseignement superieur y compris technique superieur 2178.46530 Exerce une profession Employe 1 Oui Appartenance sans pratique Le plus important Equilibre Non Non Non Oui Oui Non Non 4.0
954 56 Homme Enseignement technique ou professionnel long 4010.90211 Autre inactif Ouvrier qualifie 4 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Oui Oui 2.0
955 41 Femme Enseignement technique ou professionnel court 6350.79986 Exerce une profession Employe 1 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Non Non Non 0.0
956 71 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 2785.90046 Retraite Employe 11 Non Appartenance sans pratique NA NA Non Non Non Oui Oui Non Non 3.0
957 35 Femme Enseignement technique ou professionnel long 5834.25822 Exerce une profession NA 4 Oui Appartenance sans pratique Aussi important que le reste Insatisfaction Non Non Non Non Non Non Oui 2.0
958 67 Femme Derniere annee d’etudes primaires 5664.56976 Retraite Ouvrier specialise 1 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 3.0
959 56 Femme Derniere annee d’etudes primaires 4763.69824 Au foyer Ouvrier specialise 10 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 8.0
960 39 Homme Enseignement technique ou professionnel court 8291.11504 Exerce une profession Ouvrier qualifie 1 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Oui Non Non 2.0
961 26 Femme Enseignement technique ou professionnel court 8807.85344 Exerce une profession Employe 2 Non Pratiquant regulier Aussi important que le reste Satisfaction Non Non Non Non Non Non Oui 2.0
962 23 Femme NA 15247.24378 Etudiant, eleve NA 2 Non Rejet NA NA Non Non Non Oui Non Oui Non 0.0
963 22 Homme NA 7540.97892 Exerce une profession Ouvrier qualifie 2 Oui Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Non Non Non Oui Oui 1.1
964 48 Femme Derniere annee d’etudes primaires 506.18778 Au foyer NA 9 Oui Pratiquant regulier NA NA Non Non Non Oui Oui Oui Non 2.0
965 55 Femme 2eme cycle 4976.07552 Retraite Cadre 2 Oui Ni croyance ni appartenance NA NA Non Non Non Non Oui Non Non 1.0
966 32 Homme 2eme cycle 10576.57209 Exerce une profession Ouvrier qualifie 3 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Oui Oui Oui Non Non 2.0
967 40 Femme Enseignement superieur y compris technique superieur 5005.94165 Chomeur Employe 2 Oui Pratiquant regulier NA NA Non Non Non Non Non Oui Oui 0.7
968 67 Femme Derniere annee d’etudes primaires 4911.81371 Retraite Ouvrier specialise 2 Non Pratiquant occasionnel NA NA Non Non Non Non Oui Non Non 3.0
969 19 Femme Enseignement technique ou professionnel court 16124.20984 Autre inactif NA 1 Non Ni croyance ni appartenance NA NA Oui Non Non Non Oui Oui Oui 2.0
970 70 Femme 1er cycle 1459.76142 Retraite Employe 1 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 4.0
971 89 Homme Derniere annee d’etudes primaires 2373.63185 Retraite Ouvrier specialise 5 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 5.0
972 69 Homme Enseignement superieur y compris technique superieur 11810.39058 Retraite Cadre 1 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 2.0
973 34 Femme Enseignement superieur y compris technique superieur 8997.35334 Exerce une profession Employe 3 Oui Pratiquant occasionnel Peu important Equilibre Non Non Non Oui Non Oui Non 2.0
974 74 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 2968.15453 Retraite Employe 6 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 4.0
975 51 Femme Enseignement technique ou professionnel long 1407.06262 Exerce une profession NA 1 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Oui Non Oui 1.0
976 50 Femme 1er cycle 8147.55346 Autre inactif Employe 5 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 0.0
977 34 Homme Enseignement superieur y compris technique superieur 6393.79601 Exerce une profession NA 2 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Oui Oui Oui 0.1
978 35 Homme 1er cycle 5484.50779 Chomeur NA 1 Non Ni croyance ni appartenance NA NA Non Non Non Non Oui Non Non 3.0
979 59 Femme Derniere annee d’etudes primaires 1840.13265 Au foyer Employe 7 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 3.0
980 77 Femme 1er cycle 748.55080 Au foyer NA 2 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 1.0
981 61 Homme Enseignement superieur y compris technique superieur 3298.26755 Retraite Profession intermediaire 16 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 0.6
982 40 Homme Enseignement superieur y compris technique superieur 3765.01166 Exerce une profession Profession intermediaire 2 Oui NSP ou NVPR Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 2.9
983 48 Femme Enseignement superieur y compris technique superieur 5319.72078 Exerce une profession Profession intermediaire 0 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Oui Oui 0.0
984 77 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 10874.67952 Retire des affaires NA 0 Non Appartenance sans pratique NA NA Non Non Oui Non Non Non Non 1.0
985 59 Homme 2eme cycle 4070.23255 Retraite Cadre 2 Non Pratiquant occasionnel NA NA Non Non Non Non Oui Non Non 4.0
986 40 Femme Enseignement technique ou professionnel court 4299.69979 Exerce une profession Employe 1 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Non Non Non 4.0
987 31 Femme Enseignement technique ou professionnel court 1576.62771 Chomeur Ouvrier specialise 5 Non Appartenance sans pratique NA NA Non Non Non Non Non Oui Non 4.0
988 35 Homme Enseignement technique ou professionnel court 4673.02261 Exerce une profession Ouvrier qualifie 7 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Non Oui Non 3.0
989 52 Femme 1er cycle 6716.79935 Au foyer NA 2 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Oui 3.0
990 72 Femme Derniere annee d’etudes primaires 5620.10334 Retraite Employe 0 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 3.0
991 37 Femme Enseignement superieur y compris technique superieur 4195.84702 Chomeur Profession intermediaire 2 Non Appartenance sans pratique NA NA Non Non Non Oui Oui Oui Oui 7.0
992 64 Femme 1er cycle 3807.30215 Au foyer NA 1 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 0.0
993 63 Femme Derniere annee d’etudes primaires 1135.93140 Au foyer Ouvrier specialise 9 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 4.0
994 75 Femme 1er cycle 8365.21857 Retire des affaires NA 2 Non Pratiquant occasionnel NA NA Non Non Non Oui Oui Oui Non 5.0
995 45 Femme Derniere annee d’etudes primaires 2496.10149 Exerce une profession Employe 13 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Non Non Non 2.0
996 76 Homme Derniere annee d’etudes primaires 1989.29509 Retraite Autre 0 Non Pratiquant occasionnel NA NA Non Non Oui Non Non Non Non 0.0
997 79 Femme Derniere annee d’etudes primaires 5744.43513 Retraite Ouvrier qualifie 0 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 0.0
998 30 Homme Enseignement technique ou professionnel long 14791.81387 Exerce une profession Profession intermediaire 1 Non Appartenance sans pratique Peu important Insatisfaction Non Non Oui Non Oui Non Oui 1.0
999 56 Homme Derniere annee d’etudes primaires 2440.90180 Autre inactif Ouvrier qualifie 3 Oui Ni croyance ni appartenance NA NA Non Non Non Non Oui Non Non 4.0
1000 66 Homme Derniere annee d’etudes primaires 3406.78326 Retraite NA 4 Non Pratiquant occasionnel NA NA Non Non Non Non Oui Non Non 0.0
1001 42 Femme Enseignement technique ou professionnel long 2252.79317 Exerce une profession NA 4 Oui Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Non Oui Oui Oui Non 0.0
1002 60 Homme Enseignement technique ou professionnel court 663.98734 Chomeur Ouvrier specialise 1 Non Appartenance sans pratique NA NA Non Non Non Oui Oui Oui Non 8.0
1003 50 Homme Enseignement technique ou professionnel court 7966.27380 Exerce une profession Employe 3 Oui Pratiquant occasionnel Peu important Insatisfaction Non Non Oui Oui Oui Non Oui 1.0
1004 28 Femme Enseignement superieur y compris technique superieur 7147.28264 Exerce une profession Employe 2 Oui Appartenance sans pratique Peu important Satisfaction Non Non Non Oui Non Oui Non 2.0
1005 34 Femme 2eme cycle 14785.39348 Exerce une profession Cadre 1 Oui Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Oui Non Non Non Non Oui 5.0
1006 37 Homme 1er cycle 10645.74599 Exerce une profession Ouvrier qualifie 4 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Non Non 1.0
1007 58 Femme 2eme cycle 1159.24140 Au foyer Employe 2 Non Rejet NA NA Non Non Non Non Non Oui Oui 2.0
1008 48 Homme 1er cycle 4418.01406 Exerce une profession Ouvrier specialise 2 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Non Oui 4.0
1009 39 Homme 1er cycle 7324.08969 Exerce une profession Ouvrier qualifie 7 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Oui Oui Non Non Non 2.0
1010 43 Homme Enseignement technique ou professionnel court 2259.57719 Exerce une profession Autre 7 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 2.0
1011 57 Femme Derniere annee d’etudes primaires 4698.34779 Au foyer Ouvrier specialise 18 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 0.0
1012 31 Femme Enseignement superieur y compris technique superieur 4776.02284 Exerce une profession Employe 3 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Non Oui Oui 3.0
1013 82 Femme Enseignement technique ou professionnel court 656.80392 Au foyer Employe 3 Oui Pratiquant regulier NA NA Non Non Non Oui Non Non Non 2.0
1014 40 Homme Enseignement superieur y compris technique superieur 2321.93732 Exerce une profession Technicien 7 Non Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Non Oui Non Non 0.3
1015 48 Femme 2eme cycle 770.68482 Exerce une profession Employe 11 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Non Oui Non 2.0
1016 64 Femme N’a jamais fait d’etudes 4457.97787 Retraite Employe 3 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 4.0
1017 53 Homme Derniere annee d’etudes primaires 9721.73309 Exerce une profession Ouvrier specialise 8 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Non Non Non 3.0
1018 54 Homme Enseignement technique ou professionnel court 739.19859 Exerce une profession Ouvrier qualifie 2 Oui Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Oui Non Non Non 2.0
1019 33 Homme Enseignement technique ou professionnel long 2165.67041 Exerce une profession Cadre 5 Oui Pratiquant occasionnel Le plus important Satisfaction Non Non Non Non Non Oui Oui 0.0
1020 28 Homme Enseignement technique ou professionnel long 14830.58383 Exerce une profession Technicien 1 Non Ni croyance ni appartenance Moins important que le reste Insatisfaction Non Non Non Non Non Non Non 3.0
1021 33 Homme Enseignement technique ou professionnel court 9077.48423 Exerce une profession Employe 4 Non Ni croyance ni appartenance Moins important que le reste Insatisfaction Non Non Non Oui Non Non Oui 4.0
1022 62 Homme 1er cycle 2373.95079 Retraite Ouvrier qualifie 1 Oui NSP ou NVPR NA NA Non Non Non Non Oui Non Oui 2.0
1023 20 Femme Enseignement technique ou professionnel court 4357.16689 Exerce une profession Employe 2 Non Ni croyance ni appartenance Peu important Insatisfaction Non Non Non Non Non Non Oui 0.0
1024 57 Femme Derniere annee d’etudes primaires 2868.29030 Retire des affaires NA 7 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 4.0
1025 68 Femme Derniere annee d’etudes primaires 7060.66750 Retire des affaires NA 2 Oui Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 6.0
1026 35 Homme Enseignement technique ou professionnel court 10938.53553 Exerce une profession Ouvrier qualifie 0 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Oui Oui 3.0
1027 59 Homme Enseignement superieur y compris technique superieur 7660.77322 Exerce une profession NA 6 Non Appartenance sans pratique Moins important que le reste Equilibre Non Oui Oui Non Oui Non Non 1.0
1028 60 Homme Derniere annee d’etudes primaires 13470.76759 Retire des affaires NA 1 Non Appartenance sans pratique NA NA Non Non Non Oui Oui Oui Non 2.0
1029 31 Femme Enseignement superieur y compris technique superieur 3298.97074 Exerce une profession Employe 2 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Non Non Non 0.0
1030 53 Homme 1er cycle 5393.75021 Exerce une profession Technicien 5 Oui Appartenance sans pratique Peu important Insatisfaction Non Non Non Non Non Non Oui 2.0
1031 53 Homme 2eme cycle 2438.26388 Exerce une profession Cadre 0 Non Ni croyance ni appartenance Moins important que le reste Insatisfaction Non Non Non Non Non Non Oui 0.0
1032 63 Homme 1er cycle 11739.71031 Retire des affaires NA 2 Oui Appartenance sans pratique NA NA Non Non Oui Non Oui Non Oui 0.0
1033 46 Homme Enseignement technique ou professionnel court 571.83882 Exerce une profession Ouvrier qualifie 4 Oui Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Oui Non Oui Oui Non 3.0
1034 75 Femme Derniere annee d’etudes primaires 2381.03405 Retraite Ouvrier qualifie 9 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 2.0
1035 61 Femme Enseignement superieur y compris technique superieur 7048.26063 Retraite Profession intermediaire 0 Oui Pratiquant occasionnel NA NA Non Non Non Oui Oui Non Non 1.0
1036 32 Homme Enseignement technique ou professionnel court 697.07077 Exerce une profession Employe 3 Non Rejet Moins important que le reste Equilibre Non Non Non Non Non Oui Non 2.0
1037 32 Femme Enseignement technique ou professionnel court 1191.81641 Exerce une profession Employe 0 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Oui Oui Non 2.0
1038 53 Femme 1er cycle 4982.97912 Exerce une profession Technicien 1 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 1.0
1039 39 Femme Enseignement superieur y compris technique superieur 658.85681 Exerce une profession Cadre 1 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Non Oui Oui 2.0
1040 50 Femme Enseignement superieur y compris technique superieur 3228.11512 Chomeur Employe 7 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 1.0
1041 34 Homme Enseignement technique ou professionnel court 18081.12607 Exerce une profession Ouvrier specialise 6 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Oui Non Non Oui Oui 1.0
1042 20 Homme NA 9262.37674 Etudiant, eleve NA 1 Oui Pratiquant occasionnel NA NA Non Non Non Non Oui Oui Oui 0.4
1043 42 Femme 2eme cycle 3561.13596 Exerce une profession Employe 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Oui Oui 2.0
1044 48 Femme Enseignement superieur y compris technique superieur 3526.61710 Au foyer Cadre 4 Non Pratiquant regulier NA NA Non Non Non Non Oui Oui Non 0.3
1045 42 Femme 2eme cycle 3279.73439 Exerce une profession Profession intermediaire 0 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Oui Non Non 0.0
1046 27 Femme Enseignement technique ou professionnel long 10033.08449 Exerce une profession Employe 8 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Non Oui Non 0.0
1047 31 Femme Enseignement technique ou professionnel court 1282.84635 Exerce une profession Ouvrier qualifie 2 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Non Oui 2.0
1048 55 Homme Enseignement technique ou professionnel court 6626.08984 Exerce une profession Profession intermediaire 5 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Oui Non 3.0
1049 59 Femme Derniere annee d’etudes primaires 2756.88236 Au foyer Ouvrier specialise 1 Non Pratiquant occasionnel NA NA Non Non Non Oui Oui Non Non 3.0
1050 63 Femme Enseignement technique ou professionnel court 3748.48823 Retraite Employe 2 Oui Appartenance sans pratique NA NA Non Non Non Non Non Oui Non 0.0
1051 56 Femme Enseignement technique ou professionnel court 3936.57863 Autre inactif Employe 5 Oui Rejet NA NA Non Non Non Oui Non Non Non 4.0
1052 19 Femme NA 4680.84027 Etudiant, eleve NA 7 Ne sait pas Pratiquant regulier NA NA Non Non Non Oui Non Non Oui 0.6
1053 62 Femme Derniere annee d’etudes primaires 7239.40283 Retraite Employe 5 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 2.0
1054 46 Femme 1er cycle 945.73993 Exerce une profession Ouvrier specialise 7 Oui Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Oui Oui Non Non 0.0
1055 79 Femme 1er cycle 2134.45006 Retraite Employe 1 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 3.0
1056 19 Homme NA 12082.01628 Etudiant, eleve NA 1 Non Ni croyance ni appartenance NA NA Non Non Non Oui Oui Oui Oui 3.0
1057 34 Homme Enseignement superieur y compris technique superieur 19258.24675 Exerce une profession NA 1 Oui Rejet Moins important que le reste Satisfaction Non Non Non Non Non Oui Oui 1.0
1058 38 Femme 1er cycle 568.19342 Exerce une profession Employe 7 Non NSP ou NVPR Aussi important que le reste Satisfaction Non Non Non Non Non Oui Oui 1.4
1059 81 Femme 2eme cycle 7624.31229 Retraite Employe 1 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 2.0
1060 51 Femme 2eme cycle 2953.05057 Exerce une profession Employe 1 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Non Non Non 2.0
1061 57 Homme Enseignement technique ou professionnel court 6161.32539 Autre inactif NA 2 Non Ni croyance ni appartenance NA NA Non Non Non Non Oui Non Non 3.0
1062 36 Homme Enseignement technique ou professionnel long 4935.84745 Exerce une profession Cadre 1 Non Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 1.0
1063 31 Homme Enseignement superieur y compris technique superieur 19716.09813 Exerce une profession Cadre 1 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 0.9
1064 43 Femme 1er cycle 3678.85550 Au foyer Employe 2 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Oui Non 4.0
1065 77 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 13379.34902 Retire des affaires NA 1 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 6.0
1066 28 Homme Enseignement technique ou professionnel court 5772.69869 Exerce une profession Employe 1 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Oui Oui Oui Non Non 3.0
1067 46 Homme Enseignement technique ou professionnel court 186.48657 Exerce une profession Technicien 2 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Oui Oui Oui Non Non 2.0
1068 46 Femme 2eme cycle 18223.96609 Exerce une profession NA 10 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Non Non Non 2.0
1069 33 Homme Enseignement technique ou professionnel court 4724.40513 Chomeur Ouvrier specialise 3 Oui Appartenance sans pratique NA NA Non Non Oui Oui Non Oui Non 3.0
1070 45 Femme Enseignement technique ou professionnel court 4635.51414 Exerce une profession Employe 1 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Oui Non Non 2.0
1071 61 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 11744.22325 Retraite Employe 3 Non Pratiquant occasionnel NA NA Non Non Oui Oui Non Non Oui 2.0
1072 56 Femme Enseignement superieur y compris technique superieur 1734.26176 Exerce une profession Employe 2 Oui Pratiquant regulier Moins important que le reste Equilibre Non Non Non Non Oui Oui Oui 2.0
1073 80 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 8897.00895 Retire des affaires NA 2 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 2.0
1074 45 Homme Enseignement technique ou professionnel court 2554.17933 Exerce une profession NA 4 Non Pratiquant occasionnel Aussi important que le reste Equilibre Non Non Non Oui Oui Oui Oui 2.0
1075 68 Homme Derniere annee d’etudes primaires 10818.87421 Retraite Ouvrier qualifie 9 Oui Ni croyance ni appartenance NA NA Non Non Non Oui Non Non Non 10.0
1076 60 Homme Enseignement technique ou professionnel court 447.94659 Retraite Technicien 7 Non Appartenance sans pratique NA NA Non Non Oui Non Oui Non Non 2.0
1077 19 Homme NA 11433.02024 Etudiant, eleve NA 0 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Oui Oui 1.0
1078 33 Femme Enseignement superieur y compris technique superieur 1484.90829 Exerce une profession Autre 2 Non Pratiquant regulier Aussi important que le reste Satisfaction Non Non Non Oui Non Oui Non 3.0
1079 69 Femme 2eme cycle 5881.42070 Retraite Profession intermediaire 6 Non Pratiquant regulier NA NA Non Non Non Non Non Oui Oui 0.0
1080 55 Homme Enseignement technique ou professionnel court 236.28395 Exerce une profession Profession intermediaire 1 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Non Non 4.0
1081 72 Homme Enseignement superieur y compris technique superieur 2099.07668 Retraite Cadre 0 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Oui 3.0
1082 56 Femme 2eme cycle 6586.12976 Exerce une profession Cadre 2 Non Pratiquant occasionnel Le plus important Satisfaction Non Non Non Oui Non Oui Non 1.0
1083 81 Homme N’a jamais fait d’etudes 578.76913 Retraite Profession intermediaire 5 Non Rejet NA NA Non Non Non Non Non Non Non 6.0
1084 69 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 1083.23383 Retraite Ouvrier specialise 7 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 6.0
1085 69 Femme Enseignement technique ou professionnel court 14473.34272 Retire des affaires Ouvrier qualifie 1 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Oui 1.0
1086 80 Homme N’a jamais fait d’etudes 2430.47719 Retraite Ouvrier qualifie 14 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 0.0
1087 59 Homme Enseignement technique ou professionnel court 9710.22193 Retraite Technicien 4 Oui Ni croyance ni appartenance NA NA Non Non Oui Non Non Oui Non 3.0
1088 31 Femme Enseignement superieur y compris technique superieur 9649.04266 Exerce une profession Employe 4 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Non Oui Oui 1.0
1089 68 Homme 1er cycle 10450.28645 Retire des affaires NA 3 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 3.0
1090 53 Femme Derniere annee d’etudes primaires 1804.07001 Au foyer Employe 3 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Non Oui 4.0
1091 50 Femme Derniere annee d’etudes primaires 1246.40779 Au foyer NA 2 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 3.0
1092 29 Femme Enseignement technique ou professionnel long 5087.13153 Exerce une profession Profession intermediaire 1 Oui Pratiquant occasionnel Moins important que le reste Insatisfaction Non Non Non Oui Non Non Oui 0.0
1093 59 Femme Derniere annee d’etudes primaires 1356.81515 Exerce une profession Employe 7 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Non Oui Non 2.0
1094 30 Femme 1er cycle 1381.90287 Chomeur Employe 1 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Oui 6.0
1095 57 Femme Derniere annee d’etudes primaires 2094.23908 Chomeur Employe 6 Non Ni croyance ni appartenance NA NA Non Non Non Oui Oui Non Non 3.0
1096 76 Homme 1er cycle 2894.16414 Retraite Ouvrier qualifie 2 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 3.0
1097 49 Homme Enseignement technique ou professionnel court 10159.45526 Exerce une profession NA 4 Non Ni croyance ni appartenance Aussi important que le reste Insatisfaction Non Non Non Non Oui Non Non 3.0
1098 39 Femme Enseignement superieur y compris technique superieur 6328.48895 Exerce une profession Profession intermediaire 1 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Oui Oui Oui 0.4
1099 27 Femme NA 7627.15066 Etudiant, eleve NA 5 Non Pratiquant regulier NA NA Non Non Oui Oui Non Oui Oui 0.7
1100 24 Femme Enseignement technique ou professionnel long 8333.07459 Exerce une profession Employe 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Oui 1.0
1101 44 Femme Enseignement technique ou professionnel long 2663.37122 Exerce une profession Cadre 1 Non Rejet Moins important que le reste Equilibre Non Non Non Non Non Non Non 0.0
1102 55 Femme Enseignement superieur y compris technique superieur 8439.80977 Exerce une profession Employe 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Non 1.7
1103 37 Femme Enseignement superieur y compris technique superieur 2689.54513 Exerce une profession Cadre 1 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Non Oui Oui 4.0
1104 50 Femme Enseignement technique ou professionnel long 1703.00813 Exerce une profession Cadre 1 Oui Pratiquant occasionnel Peu important Equilibre Non Non Non Oui Oui Oui Non 0.7
1105 21 Homme NA 4427.23297 Etudiant, eleve NA 1 Oui Rejet NA NA Non Non Non Oui Non Oui Oui 2.0
1106 58 Homme Derniere annee d’etudes primaires 8724.65373 Retraite Ouvrier qualifie 3 Oui Pratiquant regulier NA NA Non Non Non Non Oui Non Non 1.0
1107 69 Femme 1er cycle 7013.44277 Retraite NA 0 Oui Pratiquant occasionnel NA NA Non Non Non Oui Oui Non Oui 2.0
1108 48 Homme Enseignement technique ou professionnel long 3518.64852 Exerce une profession Profession intermediaire 3 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Oui 2.0
1109 21 Homme Enseignement technique ou professionnel court 2545.17530 Exerce une profession Ouvrier qualifie 2 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Oui Oui Oui 2.0
1110 76 Homme Derniere annee d’etudes primaires 8200.20289 Retire des affaires NA 2 Oui Pratiquant occasionnel NA NA Non Non Non Non Oui Non Non 1.0
1111 73 Femme 1er cycle 1344.27724 Autre inactif Autre 3 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Oui Non 0.0
1112 30 Homme Enseignement technique ou professionnel court 6866.57772 Exerce une profession Ouvrier qualifie 5 Oui Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Non Non Oui Oui Non 3.0
1113 43 Femme Enseignement superieur y compris technique superieur 1405.72091 Exerce une profession NA 2 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Oui Oui Oui 0.7
1114 50 Femme Derniere annee d’etudes primaires 5336.00704 Exerce une profession Ouvrier specialise 8 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Oui Oui Oui Non Non 3.0
1115 36 Homme Enseignement technique ou professionnel long 8913.00763 Exerce une profession Profession intermediaire 1 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Oui Non Oui 2.0
1116 43 Femme Enseignement superieur y compris technique superieur 1884.06206 Exerce une profession Cadre 3 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Non Oui Oui 0.3
1117 89 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 5677.21437 Au foyer Ouvrier specialise 5 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 2.0
1118 25 Femme Enseignement technique ou professionnel long 4357.16689 Exerce une profession Employe 3 Non Pratiquant regulier Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 1.0
1119 29 Homme Enseignement superieur y compris technique superieur 7152.53470 Chomeur Employe 1 Non Ni croyance ni appartenance NA NA Oui Non Non Non Non Oui Non 0.1
1120 42 Femme Enseignement superieur y compris technique superieur 5082.68382 Exerce une profession Profession intermediaire 1 Oui Ni croyance ni appartenance Aussi important que le reste Insatisfaction Non Non Non Non Oui Non Oui 0.0
1121 26 Homme Enseignement technique ou professionnel court 5077.78122 Exerce une profession Employe 0 Non Appartenance sans pratique Moins important que le reste Equilibre Oui Non Oui Oui Oui Oui Oui 4.0
1122 90 Femme 1er cycle 14812.21576 Retraite Employe 3 Oui Pratiquant regulier NA NA Non Non Non Oui Non Non Non 5.0
1123 63 Homme Enseignement technique ou professionnel court 4633.95329 Retire des affaires NA 13 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 0.0
1124 60 Homme Enseignement superieur y compris technique superieur 7419.34150 Retraite Employe 2 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 4.0
1125 46 Femme Derniere annee d’etudes primaires 2506.06345 Exerce une profession Employe 5 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Non Non Non 2.0
1126 23 Homme NA 836.26644 Etudiant, eleve NA 2 Non Pratiquant regulier NA NA Non Non Non Non Non Oui Oui 2.0
1127 89 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 25986.09789 Autre inactif NA 2 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 0.0
1128 41 Homme Enseignement superieur y compris technique superieur 4904.07416 Exerce une profession Technicien 4 Non Rejet Moins important que le reste Satisfaction Non Non Non Non Non Oui Oui 1.4
1129 72 Femme Enseignement technique ou professionnel court 8718.80044 Retire des affaires NA 0 Non Pratiquant occasionnel NA NA Non Non Non Non Oui Non Non 5.0
1130 43 Femme Enseignement technique ou professionnel long 2686.87308 Chomeur Employe 4 Oui Appartenance sans pratique NA NA Oui Non Non Oui Oui Oui Non 3.0
1131 30 Homme Enseignement superieur y compris technique superieur 8410.55464 Exerce une profession NA 1 Non Pratiquant regulier Aussi important que le reste Satisfaction Non Non Non Oui Oui Non Oui 1.0
1132 31 Homme 1er cycle 6819.19437 Exerce une profession Ouvrier qualifie 5 Non Rejet Moins important que le reste Equilibre Non Non Non Oui Non Non Non 3.0
1133 53 Femme Derniere annee d’etudes primaires 601.57834 Exerce une profession Ouvrier qualifie 13 Oui Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Non Non Non Oui 1.0
1134 72 Femme Enseignement superieur y compris technique superieur 5936.30907 Retraite Cadre 2 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Oui Oui 1.1
1135 42 Femme Enseignement superieur y compris technique superieur 7741.26613 Au foyer Profession intermediaire 8 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 1.0
1136 48 Homme Enseignement superieur y compris technique superieur 4916.19198 Exerce une profession Cadre 1 Oui Pratiquant regulier Aussi important que le reste Satisfaction Non Oui Non Non Oui Oui Oui 0.1
1137 40 Femme 2eme cycle 4561.49562 Exerce une profession Employe 2 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Non Non Oui 1.0
1138 70 Homme Derniere annee d’etudes primaires 771.69306 Retraite Ouvrier qualifie 0 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Non Oui 3.0
1139 54 Femme Enseignement technique ou professionnel court 5233.73581 Au foyer Employe 0 Non Appartenance sans pratique NA NA Non Non Non Oui Oui Non Non 2.0
1140 26 Homme 1er cycle 5543.89176 Chomeur Ouvrier specialise 2 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Oui 2.0
1141 33 Femme Enseignement technique ou professionnel court 8601.02300 Exerce une profession Employe 3 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Non Non 3.0
1142 24 Homme Enseignement technique ou professionnel court 6721.18690 Exerce une profession Ouvrier qualifie 2 Non Ni croyance ni appartenance Moins important que le reste Insatisfaction Non Non Non Oui Oui Oui Oui 2.0
1143 69 Homme Enseignement technique ou professionnel court 5386.85960 Retraite Ouvrier qualifie 3 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 6.0
1144 49 Homme Derniere annee d’etudes primaires 1175.08724 Autre inactif Ouvrier qualifie 9 Non Ni croyance ni appartenance NA NA Non Non Oui Non Non Non Non 4.0
1145 50 Femme Enseignement superieur y compris technique superieur 2224.91103 Exerce une profession Profession intermediaire 0 Oui Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Oui Non Non Oui 2.0
1146 28 Homme Enseignement technique ou professionnel court 25717.20258 Exerce une profession Ouvrier qualifie 1 Oui Appartenance sans pratique Aussi important que le reste Equilibre Non Non Oui Oui Oui Non Non 2.0
1147 63 Homme Enseignement technique ou professionnel court 6021.23323 Retraite Technicien 3 Non Appartenance sans pratique NA NA Non Non Oui Oui Oui Non Non 3.0
1148 63 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 11891.59145 Retire des affaires NA 2 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 0.0
1149 37 Femme Enseignement technique ou professionnel court 701.01689 Exerce une profession Employe 1 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Oui Oui Non 2.0
1150 69 Homme Enseignement superieur y compris technique superieur 12419.08920 Retraite Cadre 5 Oui Pratiquant occasionnel NA NA Non Oui Non Non Non Oui Oui 0.4
1151 91 Homme Derniere annee d’etudes primaires 4291.00879 Retire des affaires NA 3 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 0.0
1152 66 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 6438.15359 Retraite Ouvrier specialise 2 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 4.0
1153 56 Homme Enseignement technique ou professionnel long 935.32185 Exerce une profession Ouvrier qualifie 9 Oui Appartenance sans pratique Aussi important que le reste Insatisfaction Non Non Non Oui Oui Non Non 3.0
1154 37 Femme Enseignement superieur y compris technique superieur 6165.34358 Exerce une profession Employe 4 Non Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Non Oui Oui Oui Non 0.4
1155 67 Femme Enseignement technique ou professionnel court 1819.49908 Retire des affaires NA 5 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Oui 1.0
1156 20 Femme NA 7435.75946 Etudiant, eleve NA 2 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Oui Oui 2.0
1157 38 Femme 2eme cycle 2822.24691 Exerce une profession Employe 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Non 1.0
1158 48 Femme Enseignement superieur y compris technique superieur 7940.67704 Au foyer Employe 9 Non Rejet NA NA Non Non Non Non Oui Oui Oui 3.0
1159 34 Femme Enseignement technique ou professionnel court 5775.91347 Exerce une profession Ouvrier qualifie 1 Oui Rejet Moins important que le reste Satisfaction Non Non Oui Non Oui Non Non 3.0
1160 61 Homme Enseignement technique ou professionnel court 3856.44013 Retraite NA 0 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Oui 4.0
1161 40 Femme Enseignement technique ou professionnel court 4561.49562 Exerce une profession Autre 2 Non Rejet Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 3.0
1162 27 Femme Enseignement superieur y compris technique superieur 9207.51095 Exerce une profession Cadre 3 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Oui Oui 1.0
1163 61 Femme Enseignement technique ou professionnel court 13026.12228 Retraite Employe 1 Non Appartenance sans pratique NA NA Non Non Non Oui Non Oui Oui 2.0
1164 21 Femme NA 10198.30162 Etudiant, eleve NA 2 Non Ni croyance ni appartenance NA NA Non Non Oui Non Non Oui Non 0.7
1165 29 Femme Enseignement technique ou professionnel court 3626.61507 Au foyer Employe 1 Oui Pratiquant regulier NA NA Non Non Non Oui Oui Non Oui 2.0
1166 31 Femme Enseignement superieur y compris technique superieur 4938.34436 Exerce une profession Cadre 2 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 3.0
1167 24 Femme Enseignement technique ou professionnel court 7975.01739 Exerce une profession Employe 1 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Oui Oui Non 1.0
1168 31 Femme 2eme cycle 10213.32919 Exerce une profession Employe 1 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Oui Oui 0.0
1169 54 Homme Enseignement technique ou professionnel court 4394.62743 Autre inactif Ouvrier specialise 0 Non Appartenance sans pratique NA NA Non Non Oui Non Oui Non Non 3.0
1170 66 Homme Derniere annee d’etudes primaires 5436.53925 Retraite Employe 5 Non Pratiquant occasionnel NA NA Non Non Non Non Oui Non Non 6.0
1171 63 Homme Enseignement superieur y compris technique superieur 1386.57287 Retraite Cadre 3 Oui Appartenance sans pratique NA NA Non Non Oui Non Oui Oui Oui 3.0
1172 56 Femme 2eme cycle 2910.79675 Exerce une profession Profession intermediaire 5 Oui Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Oui Non Oui Non 2.0
1173 71 Homme Enseignement superieur y compris technique superieur 4921.91931 Retraite Cadre 2 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 2.0
1174 59 Homme Enseignement superieur y compris technique superieur 793.82878 Exerce une profession Cadre 9 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Non Non Non 2.0
1175 20 Femme Enseignement technique ou professionnel long 7178.21966 Exerce une profession Employe 5 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 3.0
1176 31 Homme 2eme cycle 6819.19437 Exerce une profession Cadre 2 Non Rejet Aussi important que le reste Equilibre Non Non Oui Non Oui Non Non 0.0
1177 19 Femme NA 4629.22907 Etudiant, eleve NA 0 Oui Ni croyance ni appartenance NA NA Non Non Non Non Oui Oui Non 0.4
1178 39 Homme 2eme cycle 8263.30157 Exerce une profession Technicien 0 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Oui Non Oui 2.0
1179 61 Femme Enseignement technique ou professionnel court 9733.98656 Retraite NA 3 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 0.0
1180 69 Homme 2eme cycle 18190.65372 Retraite Cadre 1 Oui Appartenance sans pratique NA NA Non Non Non Non Non Oui Oui 2.0
1181 40 Femme 2eme cycle 1112.23537 Exerce une profession NA 2 Oui Rejet Moins important que le reste Equilibre Non Non Non Oui Non Non Oui 0.0
1182 40 Femme Enseignement technique ou professionnel long 1271.53792 Exerce une profession Cadre 8 Non Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Oui Non Oui Non Non Non 3.0
1183 58 Homme Enseignement technique ou professionnel court 1305.25166 Chomeur Ouvrier qualifie 4 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Oui Oui 3.0
1184 40 Femme 1er cycle 5589.29095 Chomeur Employe 5 Non NSP ou NVPR NA NA Non Non Non Oui Non Non Oui 2.0
1185 65 Homme Enseignement technique ou professionnel long 3412.08786 Retraite Profession intermediaire 0 Non Ni croyance ni appartenance NA NA Non Non Non Oui Oui Non Oui 3.0
1186 53 Femme 1er cycle 4731.46379 Au foyer Employe 7 Non Ni croyance ni appartenance NA NA Non Non Non Oui Non Non Non 4.0
1187 48 Homme Derniere annee d’etudes primaires 1257.11628 Exerce une profession Ouvrier qualifie 3 Non Pratiquant occasionnel Aussi important que le reste Equilibre Non Non Non Oui Non Non Non 4.0
1188 63 Femme 1er cycle 4045.69044 Retraite Cadre 1 Non Pratiquant regulier NA NA Non Non Non Oui Oui Non Non 2.0
1189 38 Femme Enseignement technique ou professionnel court 11104.48783 Au foyer Ouvrier qualifie 2 Oui NSP ou NVPR NA NA Non Non Non Oui Non Oui Non 4.0
1190 38 Homme Enseignement superieur y compris technique superieur 4730.33839 Exerce une profession Cadre 1 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 0.4
1191 56 Femme Enseignement technique ou professionnel long 6598.49523 Exerce une profession Profession intermediaire 1 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Non Non 3.0
1192 65 Homme Enseignement superieur y compris technique superieur 1716.02068 Retraite Cadre 2 Oui Ni croyance ni appartenance NA NA Non Non Non Non Oui Non Non 3.0
1193 69 Femme Derniere annee d’etudes primaires 10356.23866 Retraite Ouvrier qualifie 6 Non Rejet NA NA Non Non Non Oui Non Non Non 0.0
1194 23 Femme 1er cycle 4809.18016 Chomeur NA 4 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 6.0
1195 50 Homme Enseignement superieur y compris technique superieur 3951.32537 Exerce une profession Cadre 3 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Non Non Oui 1.0
1196 55 Femme Enseignement superieur y compris technique superieur 1553.31958 Exerce une profession Employe 4 Non NSP ou NVPR Moins important que le reste Equilibre Non Non Non Oui Oui Non Non 2.0
1197 50 Femme Enseignement technique ou professionnel court 2345.04257 Exerce une profession NA 1 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 2.0
1198 45 Homme Derniere annee d’etudes primaires 3653.29666 Chomeur Ouvrier specialise 8 Non Pratiquant regulier NA NA Non Non Non Oui Oui Non Non 5.0
1199 50 Femme 2eme cycle 5082.06136 Exerce une profession Profession intermediaire 3 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Oui Oui Non 0.0
1200 74 Femme 1er cycle 7821.64355 Retraite Ouvrier specialise 1 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 9.0
1201 50 Homme Derniere annee d’etudes primaires 1289.86318 Exerce une profession Employe 7 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Oui 3.0
1202 49 Homme Enseignement superieur y compris technique superieur 1867.24312 Exerce une profession Cadre 2 Oui Pratiquant regulier Aussi important que le reste Satisfaction Non Non Non Non Oui Oui Oui 0.1
1203 35 Homme Enseignement superieur y compris technique superieur 4079.20867 Exerce une profession Cadre 11 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Non Oui Oui 2.0
1204 35 Femme Enseignement technique ou professionnel court 3824.72988 Au foyer Employe 2 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Oui Oui 2.0
1205 33 Homme Enseignement superieur y compris technique superieur 3540.43993 Exerce une profession Cadre 5 Non NSP ou NVPR Moins important que le reste Satisfaction Non Oui Oui Non Oui Oui Non 2.0
1206 51 Femme Enseignement superieur y compris technique superieur 5968.53055 Exerce une profession Profession intermediaire 2 Oui Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Non Oui Non Non Non 1.0
1207 23 Femme Enseignement technique ou professionnel long 7147.28264 Exerce une profession Ouvrier qualifie 1 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Oui Non 3.0
1208 26 Femme Enseignement superieur y compris technique superieur 6446.60640 Exerce une profession Cadre 3 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 1.0
1209 44 Homme Derniere annee d’etudes primaires 1355.79604 Exerce une profession Ouvrier qualifie 11 Oui Appartenance sans pratique Aussi important que le reste Insatisfaction Non Non Non Non Oui Non Non 0.0
1210 60 Homme Enseignement superieur y compris technique superieur 2762.64877 Exerce une profession NA 3 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Non Non Non 2.1
1211 18 Homme Enseignement technique ou professionnel court 14254.28150 Exerce une profession Ouvrier specialise 1 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Non 5.0
1212 54 Femme Enseignement technique ou professionnel court 1907.25291 Exerce une profession Employe 1 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Non Non Oui 4.0
1213 18 Femme 2eme cycle 4909.69949 Chomeur NA 4 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Oui Non 10.0
1214 30 Femme Enseignement technique ou professionnel long 2866.46809 Au foyer Ouvrier qualifie 2 Non Appartenance sans pratique NA NA Non Non Non Oui Oui Non Non 5.0
1215 46 Homme Derniere annee d’etudes primaires 820.08280 Exerce une profession Ouvrier qualifie 11 Non Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Oui Oui Oui Non Non 1.0
1216 48 Femme Enseignement superieur y compris technique superieur 14689.64554 Exerce une profession Cadre 5 Oui Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Oui Non Oui Oui Oui Oui 3.0
1217 50 Femme Enseignement technique ou professionnel long 4626.01172 Exerce une profession Employe 1 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Oui Oui Non 4.0
1218 64 Femme Derniere annee d’etudes primaires 1182.87991 Au foyer Employe 4 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 1.0
1219 25 Femme Enseignement superieur y compris technique superieur 6446.60640 Exerce une profession Employe 1 Non Pratiquant regulier Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 0.4
1220 25 Homme Enseignement superieur y compris technique superieur 3462.14491 Exerce une profession Cadre 5 Oui Appartenance sans pratique Le plus important Satisfaction Non Non Non Non Oui Oui Oui 0.4
1221 49 Femme Enseignement technique ou professionnel court 1508.17207 Exerce une profession Employe 4 Non Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Oui Oui Non Non 1.0
1222 28 Femme Enseignement superieur y compris technique superieur 14685.75090 Exerce une profession Technicien 0 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Oui Oui 0.0
1223 81 Femme Derniere annee d’etudes primaires 2030.90065 Retraite Employe 3 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Non Oui 3.0
1224 37 Homme Enseignement superieur y compris technique superieur 742.96222 Exerce une profession Profession intermediaire 3 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 1.0
1225 22 Femme NA 4253.38318 Etudiant, eleve NA 1 Oui Ni croyance ni appartenance NA NA Oui Non Non Oui Oui Oui Oui 0.3
1226 24 Femme Enseignement technique ou professionnel long 3354.54696 Chomeur Employe 2 Oui Appartenance sans pratique NA NA Non Non Non Oui Oui Oui Oui 4.0
1227 68 Homme N’a jamais fait d’etudes 1285.45223 Retraite Ouvrier qualifie 6 Non Pratiquant occasionnel NA NA Non Non Non Non Oui Non Non 2.0
1228 47 Femme Enseignement technique ou professionnel court 742.04353 Exerce une profession Profession intermediaire 4 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Oui Non Non Non Non 1.0
1229 72 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 797.66048 Autre inactif Ouvrier specialise 5 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 2.0
1230 58 Femme Derniere annee d’etudes primaires 943.79546 Autre inactif Ouvrier qualifie 2 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 3.0
1231 50 Femme Enseignement technique ou professionnel court 6143.52233 Exerce une profession NA 9 Oui Pratiquant regulier Aussi important que le reste Satisfaction Non Non Non Oui Oui Non Non 1.0
1232 42 Homme Enseignement superieur y compris technique superieur 10181.68215 Exerce une profession Profession intermediaire 2 Oui Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Non Non Non Oui Non 0.0
1233 59 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 1423.49844 Autre inactif Ouvrier qualifie 5 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 1.0
1234 19 Femme NA 7128.36274 Etudiant, eleve NA 0 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Oui Non 0.3
1235 40 Femme Enseignement superieur y compris technique superieur 2666.17386 Exerce une profession NA 2 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Non Oui Oui 0.4
1236 78 Homme Derniere annee d’etudes primaires 1594.26815 Retraite Ouvrier qualifie 13 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 0.0
1237 52 Homme Derniere annee d’etudes primaires 2852.06361 Exerce une profession Employe 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Non Oui NA
1238 44 Homme 2eme cycle 4238.82222 Exerce une profession Employe 5 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Non Oui Non 2.0
1239 55 Femme 2eme cycle 1255.47069 Retraite Autre 6 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 0.0
1240 53 Femme 2eme cycle 7796.57988 Exerce une profession Cadre 1 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Oui Oui 2.0
1241 36 Femme Enseignement technique ou professionnel court 3752.87941 Exerce une profession Employe 6 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Non Oui 7.0
1242 27 Femme Enseignement technique ou professionnel court 3501.18279 Exerce une profession Ouvrier specialise 3 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Non Non 2.0
1243 21 Homme Enseignement technique ou professionnel court 10229.89836 Exerce une profession Ouvrier specialise 2 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Oui Non 2.0
1244 37 Homme Enseignement technique ou professionnel long 7665.92434 Exerce une profession Cadre 4 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Oui Oui Oui 2.0
1245 57 Homme Enseignement technique ou professionnel court 980.07778 Exerce une profession NA 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Non Oui 3.0
1246 68 Femme Derniere annee d’etudes primaires 13390.01272 Retire des affaires NA 2 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 5.0
1247 73 Femme Derniere annee d’etudes primaires 11104.34532 Retire des affaires NA 3 Non Pratiquant regulier NA NA Non Non Non Non Oui Non Non 3.0
1248 44 Femme Derniere annee d’etudes primaires 2434.90451 Exerce une profession Employe 1 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Non 0.0
1249 29 Homme Enseignement superieur y compris technique superieur 5731.66151 Exerce une profession Autre 2 Non Pratiquant regulier Aussi important que le reste Satisfaction Non Non Non Oui Non Oui Oui 2.0
1250 19 Femme NA 5689.92659 Exerce une profession Autre 2 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Oui Oui Oui Oui Oui 2.0
1251 30 Femme 1er cycle 4610.32030 Exerce une profession Employe 2 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Non Oui Non 5.0
1252 50 Femme Derniere annee d’etudes primaires 965.12018 Au foyer Ouvrier specialise 7 Ne sait pas Pratiquant regulier NA NA Non Non Non Oui Non Non Oui 3.0
1253 33 Femme Enseignement superieur y compris technique superieur 9380.68243 Exerce une profession Employe 2 Oui Pratiquant occasionnel Peu important Satisfaction Non Non Non Non Non Non Oui 3.0
1254 52 Homme Enseignement superieur y compris technique superieur 2176.72982 Chomeur Employe 15 Oui Appartenance sans pratique NA NA Non Non Non Oui Oui Oui Non 1.0
1255 45 Femme Enseignement technique ou professionnel court 2836.91882 Exerce une profession Employe 1 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Non Oui Oui 0.4
1256 44 Femme Enseignement superieur y compris technique superieur 3312.59794 Au foyer NA 3 Non Appartenance sans pratique NA NA Non Non Non Oui Oui Non Non 3.0
1257 53 Femme 1er cycle 23967.67323 Exerce une profession Employe 11 Non Pratiquant regulier Moins important que le reste Insatisfaction Non Non Non Non Non Non Non 3.0
1258 39 Femme Enseignement technique ou professionnel court 7379.76263 Au foyer Employe 5 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 2.0
1259 48 Femme Derniere annee d’etudes primaires 8032.88667 Au foyer Employe 5 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 6.0
1260 44 Femme N’a jamais fait d’etudes 2462.00492 Au foyer NA 7 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 3.0
1261 18 Homme Enseignement technique ou professionnel court 6789.11327 Chomeur NA 5 Non Pratiquant occasionnel NA NA Non Non Non Non Non Oui Oui 5.0
1262 46 Femme Enseignement superieur y compris technique superieur 4174.23584 Exerce une profession Profession intermediaire 1 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Non Oui Oui 0.0
1263 48 Femme Derniere annee d’etudes primaires 628.80379 Exerce une profession Ouvrier qualifie 8 Oui Ni croyance ni appartenance Peu important Insatisfaction Non Non Non Oui Non Non Non 1.0
1264 49 Femme 2eme cycle 2038.82262 Exerce une profession Autre 0 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Non Non 2.0
1265 37 Homme Enseignement technique ou professionnel court 17590.35577 Exerce une profession Ouvrier qualifie 4 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Oui Non 1.0
1266 55 Femme Derniere annee d’etudes primaires 8128.86098 Exerce une profession Employe 5 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Oui Non Oui Oui Oui 4.0
1267 78 Homme 2eme cycle 894.66958 Retraite Ouvrier qualifie 0 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 3.0
1268 58 Femme Enseignement technique ou professionnel court 8489.53405 Au foyer Employe 0 Oui Appartenance sans pratique NA NA Non Non Non Oui Oui Non Oui 1.0
1269 48 Femme Derniere annee d’etudes primaires 14556.11624 Chomeur Employe 6 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 2.0
1270 80 Homme Enseignement superieur y compris technique superieur 7020.52269 Retraite Cadre 7 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Non Oui 3.0
1271 48 Femme 1er cycle 4863.12835 Au foyer Ouvrier specialise 4 Non NSP ou NVPR NA NA Non Non Non Oui Non Non Non 4.0
1272 30 Homme Enseignement technique ou professionnel court 2195.05061 Exerce une profession Ouvrier qualifie 3 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Oui Oui Oui Oui Oui 5.0
1273 64 Homme Enseignement technique ou professionnel court 7739.34928 Retraite Ouvrier qualifie 2 Non Pratiquant occasionnel NA NA Non Non Oui Non Oui Non Oui 4.0
1274 26 Homme Enseignement technique ou professionnel long 5921.66557 Exerce une profession Employe 1 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Non Oui Oui 4.0
1275 45 Femme 1er cycle 1420.26694 Exerce une profession Ouvrier specialise 4 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Non Oui Non 1.0
1276 52 Homme 1er cycle 1523.80430 Chomeur Ouvrier specialise 7 Oui Ni croyance ni appartenance NA NA Non Non Non Non Oui Non Non 5.0
1277 66 Femme Derniere annee d’etudes primaires 5463.26829 Retire des affaires NA 4 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 2.0
1278 41 Femme 1er cycle 656.05756 Exerce une profession Employe 4 Oui Pratiquant regulier Moins important que le reste Equilibre Non Non Non Oui Non Oui Non 2.0
1279 70 Femme Enseignement superieur y compris technique superieur 13572.65669 Retraite Employe 0 Non Pratiquant occasionnel NA NA Non Non Non Oui Oui Oui Non 1.0
1280 44 Femme N’a jamais fait d’etudes 1873.69142 Exerce une profession Autre 5 Non Pratiquant regulier Le plus important Satisfaction Non Non Non Non Non Non Non 1.0
1281 63 Homme Derniere annee d’etudes primaires 8411.92320 Retraite Cadre 2 Oui Appartenance sans pratique NA NA Non Non Non Oui Oui Oui Non 6.0
1282 56 Homme Derniere annee d’etudes primaires 127.90122 Exerce une profession Ouvrier specialise 12 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Non Non 1.0
1283 75 Femme Derniere annee d’etudes primaires 5322.90478 Retraite NA 1 Non Pratiquant occasionnel NA NA Non Non Oui Oui Non Non Oui 5.0
1284 77 Femme Derniere annee d’etudes primaires 12102.70990 Retire des affaires NA 3 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Oui Non 4.0
1285 31 Homme Enseignement superieur y compris technique superieur 6781.55643 Exerce une profession Technicien 2 Non Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Non Non Non Non Oui 2.0
1286 59 Homme Enseignement technique ou professionnel court 4911.51739 Autre inactif NA 9 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 2.0
1287 43 Femme Enseignement superieur y compris technique superieur 6543.77244 Exerce une profession Profession intermediaire 4 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 2.0
1288 50 Homme 1er cycle 1551.67586 Autre inactif Technicien 6 Non Rejet NA NA Non Non Non Non Non Non Non 2.0
1289 71 Femme 2eme cycle 2802.79957 Retraite Employe 1 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 4.0
1290 20 Homme NA 7011.94742 Etudiant, eleve NA 2 Oui Ni croyance ni appartenance NA NA Non Non Non Oui Oui Oui Oui 2.0
1291 30 Femme Enseignement superieur y compris technique superieur 5513.76263 Exerce une profession Cadre 0 Oui Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Non Oui Oui Oui 1.0
1292 63 Femme Derniere annee d’etudes primaires 3010.88639 Retraite Employe 1 Non Appartenance sans pratique NA NA Non Non Non Oui Oui Non Non 2.0
1293 66 Femme Derniere annee d’etudes primaires 3244.45391 Retraite Employe 7 Non Pratiquant regulier NA NA Non Non Non Non Oui Non Non 5.0
1294 34 Femme Enseignement superieur y compris technique superieur 4181.20865 Exerce une profession Employe 2 Oui Rejet Moins important que le reste Equilibre Non Non Non Oui Non Non Oui 3.0
1295 45 Femme Enseignement superieur y compris technique superieur 1067.59985 Exerce une profession Employe 1 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Non Non 2.0
1296 36 Homme Enseignement technique ou professionnel court 1521.31976 Chomeur Ouvrier qualifie 1 Non Appartenance sans pratique NA NA Non Non Non Non Oui Oui Oui 4.0
1297 70 Femme 1er cycle 3715.92369 Retraite Employe 5 Oui Ni croyance ni appartenance NA NA Non Non Non Oui Non Non Oui 3.0
1298 68 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 5357.15447 Retraite Employe 3 Non Pratiquant regulier NA NA Non Non Non Non Non Oui Non 4.0
1299 47 Homme Enseignement technique ou professionnel court 2221.92633 Exerce une profession Ouvrier qualifie 3 Oui Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Oui Non Non Oui 2.0
1300 53 Femme 2eme cycle 6495.10090 Exerce une profession Cadre 2 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 2.0
1301 74 Homme 2eme cycle 1179.39286 Retraite Technicien 3 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 1.1
1302 55 Femme Enseignement technique ou professionnel long 6743.98564 Retraite Cadre 8 Non Pratiquant occasionnel NA NA Non Non Non Non Oui Oui Oui 2.0
1303 45 Homme Derniere annee d’etudes primaires 2741.46086 Exerce une profession Ouvrier qualifie 7 Non Appartenance sans pratique Aussi important que le reste Insatisfaction Non Non Non Non Oui Non Non 5.0
1304 26 Homme Enseignement superieur y compris technique superieur 3358.41734 Exerce une profession Technicien 1 Oui Ni croyance ni appartenance Aussi important que le reste Insatisfaction Non Non Non Oui Oui Oui Oui 2.0
1305 39 Femme 2eme cycle 6505.62747 Exerce une profession Employe 1 Non Appartenance sans pratique Peu important Insatisfaction Non Non Non Oui Non Oui Oui 2.0
1306 49 Homme Enseignement technique ou professionnel court 5933.35310 Exerce une profession Employe 4 Non Pratiquant occasionnel Aussi important que le reste Equilibre Non Non Non Non Oui Non Non 1.0
1307 67 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 5537.89340 Retraite Employe 5 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 5.0
1308 64 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 5733.79951 Autre inactif Ouvrier specialise 2 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Oui 4.0
1309 21 Homme Enseignement technique ou professionnel long 4249.14230 Exerce une profession Employe 3 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 3.0
1310 50 Femme Enseignement superieur y compris technique superieur 702.41049 Au foyer Profession intermediaire 1 Oui Appartenance sans pratique NA NA Non Non Non Non Non Oui Oui 4.0
1311 53 Femme Derniere annee d’etudes primaires 7534.55552 Autre inactif Ouvrier qualifie 0 Non Pratiquant regulier NA NA Non Non Non Non Oui Non Non 3.0
1312 58 Homme Enseignement superieur y compris technique superieur 3861.21578 Exerce une profession Cadre 2 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Non Oui 1.0
1313 45 Femme 1er cycle 2295.90668 Exerce une profession Employe 8 Oui NSP ou NVPR Moins important que le reste Insatisfaction Non Non Non Non Oui Oui Non 3.0
1314 33 Homme Enseignement superieur y compris technique superieur 3390.77822 Exerce une profession Cadre 1 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Non 2.0
1315 23 Homme 2eme cycle 2107.72266 Exerce une profession Ouvrier qualifie 2 Oui Pratiquant regulier Moins important que le reste Insatisfaction Non Non Non Non Oui Oui Oui 2.0
1316 77 Femme 1er cycle 3354.45513 Autre inactif Employe 14 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 4.0
1317 34 Femme Enseignement superieur y compris technique superieur 7402.62721 Exerce une profession Employe 1 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Oui Oui 2.1
1318 73 Femme N’a jamais fait d’etudes 3060.23193 Autre inactif Ouvrier specialise 6 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 2.0
1319 35 Femme Enseignement superieur y compris technique superieur 2600.23846 Exerce une profession Cadre 3 Oui Ni croyance ni appartenance Peu important Insatisfaction Non Non Non Oui Non Oui Non 1.7
1320 55 Homme Enseignement superieur y compris technique superieur 14293.47793 Exerce une profession NA 1 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Non Non 1.0
1321 41 Homme Enseignement technique ou professionnel court 8970.42292 Exerce une profession Ouvrier specialise 11 Oui Ni croyance ni appartenance Moins important que le reste Insatisfaction Non Non Non Non Non Non Oui 4.0
1322 24 Homme 1er cycle 8193.01193 Exerce une profession Ouvrier qualifie 1 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 4.0
1323 66 Homme Derniere annee d’etudes primaires 5126.65983 Retraite Ouvrier qualifie 6 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 6.0
1324 40 Homme 1er cycle 2257.92794 Chomeur Ouvrier specialise 8 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Oui 11.0
1325 33 Homme Enseignement superieur y compris technique superieur 3581.91828 Exerce une profession Autre 1 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Non Oui 2.0
1326 47 Femme Enseignement technique ou professionnel court 2763.38783 Autre inactif NA 3 Non Pratiquant occasionnel NA NA Non Non Non Oui Oui Non Non 2.0
1327 23 Femme Enseignement superieur y compris technique superieur 3176.41916 Chomeur Ouvrier specialise 2 Non Ni croyance ni appartenance NA NA Non Non Non Non Oui Oui Oui 3.0
1328 61 Femme Enseignement superieur y compris technique superieur 7453.34975 Retraite Employe 7 Oui Ni croyance ni appartenance NA NA Non Non Non Oui Oui Oui Oui 3.0
1329 68 Femme Enseignement technique ou professionnel court 5854.28376 Retraite Employe 1 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 0.0
1330 52 Femme Enseignement superieur y compris technique superieur 7930.68447 Exerce une profession Technicien 2 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Oui Non Non Non Oui 2.0
1331 50 Femme 2eme cycle 3845.54171 Exerce une profession Employe 1 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Non Non 2.0
1332 65 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 7230.27918 Retraite Employe 5 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 3.0
1333 18 Femme NA 4760.38247 Etudiant, eleve NA 2 Non Pratiquant regulier NA NA Non Non Non Oui Oui Oui Non 0.0
1334 37 Femme 2eme cycle 4244.16325 Exerce une profession Employe 0 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Oui Non Non Non Non 3.0
1335 26 Homme 1er cycle 7619.96849 Exerce une profession Ouvrier specialise 3 Non Ni croyance ni appartenance Peu important Insatisfaction Non Non Non Non Non Non Oui 3.0
1336 33 Homme 2eme cycle 4736.37197 Exerce une profession Cadre 2 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Oui Oui Oui 0.9
1337 36 Femme 1er cycle 4329.01048 Chomeur Employe 6 Oui Ni croyance ni appartenance NA NA Non Non Non Oui Oui Non Oui 4.0
1338 47 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 4972.17290 Chomeur Employe 14 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 0.0
1339 70 Homme Enseignement technique ou professionnel court 5815.08645 Retraite Profession intermediaire 1 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 2.0
1340 55 Homme Enseignement technique ou professionnel court 6250.29609 Exerce une profession Technicien 1 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Non Non 2.0
1341 39 Femme Enseignement technique ou professionnel court 26178.58682 Au foyer Employe 3 Oui Appartenance sans pratique NA NA Non Non Non Non Non Oui Non 5.0
1342 19 Femme Enseignement technique ou professionnel court 8780.26142 Exerce une profession Employe 2 Non Pratiquant regulier Aussi important que le reste Insatisfaction Non Non Non Oui Non Oui Oui 2.0
1343 67 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 7709.51312 Au foyer Ouvrier specialise 5 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 2.0
1344 75 Femme 2eme cycle 17240.87381 Retire des affaires NA 1 Non Appartenance sans pratique NA NA Non Non Non Oui Oui Non Non 3.0
1345 31 Homme Enseignement superieur y compris technique superieur 6139.86587 Exerce une profession Cadre 1 Non Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Oui Oui Oui Oui 1.0
1346 48 Femme 1er cycle 745.01656 Exerce une profession Employe 3 Non Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Non Non Non Non 0.1
1347 41 Femme 1er cycle 1165.68739 Au foyer NA 3 Non Appartenance sans pratique NA NA Non Non Non Oui Oui Non Non 1.0
1348 46 Homme Enseignement superieur y compris technique superieur 2800.79496 Exerce une profession Cadre 2 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Oui Oui Non 0.0
1349 39 Homme Enseignement technique ou professionnel court 1263.40704 Exerce une profession Employe 0 Non Rejet Moins important que le reste Equilibre Non Non Non Oui Non Oui Non 2.0
1350 69 Femme Derniere annee d’etudes primaires 7605.69205 Retraite Employe 4 Oui Pratiquant regulier NA NA Non Non Non Oui Non Non Non 3.0
1351 78 Femme Derniere annee d’etudes primaires 3280.87763 Autre inactif Employe 2 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 1.0
1352 47 Homme Enseignement superieur y compris technique superieur 8881.53352 Exerce une profession Cadre 1 Oui Pratiquant occasionnel Aussi important que le reste Equilibre Non Non Non Oui Oui Non Non 1.0
1353 59 Homme Derniere annee d’etudes primaires 1242.37048 Autre inactif Cadre 6 Non Appartenance sans pratique NA NA Non Non Non Oui Non Oui Non 3.0
1354 47 Femme Enseignement technique ou professionnel long 7276.69365 Exerce une profession Cadre 1 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Oui Oui Non Oui Oui Oui 3.0
1355 55 Femme Enseignement technique ou professionnel court 8415.73307 Exerce une profession NA 3 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Non Non Non 0.0
1356 67 Homme 2eme cycle 5408.65322 Retraite Cadre 3 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Oui Non 0.0
1357 21 Homme NA 9262.37674 Etudiant, eleve NA 6 Non Pratiquant occasionnel NA NA Non Non Non Non Non Oui Oui 2.0
1358 34 Femme Enseignement superieur y compris technique superieur 14753.62571 Au foyer NA 4 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 2.0
1359 65 Femme Derniere annee d’etudes primaires 1172.47491 Au foyer Employe 4 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 0.1
1360 42 Femme Derniere annee d’etudes primaires 1346.09063 Exerce une profession Employe 2 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Non Non Non 5.0
1361 79 Homme 1er cycle 6181.82000 Retraite Cadre 6 Non Pratiquant occasionnel NA NA Non Non Non Oui Oui Non Non 3.0
1362 73 Femme 1er cycle 6889.07086 Retraite Employe 0 Oui Pratiquant regulier NA NA Non Non Oui Oui Non Non Non 3.0
1363 45 Femme Enseignement technique ou professionnel court 4513.99466 Exerce une profession Employe 1 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Non Non Non 2.0
1364 39 Femme 2eme cycle 2322.92350 Exerce une profession Autre 1 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Oui Oui Oui 2.0
1365 42 Femme 2eme cycle 3680.18981 Au foyer Employe 2 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Oui 0.0
1366 56 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 6495.10090 Exerce une profession Employe 4 Oui Pratiquant regulier Moins important que le reste Equilibre Non Non Non Non Non Oui Non 3.0
1367 46 Femme 1er cycle 6465.66395 Exerce une profession Employe 4 Oui Ni croyance ni appartenance Aussi important que le reste Insatisfaction Non Non Non Non Non Oui Oui 3.0
1368 42 Homme Enseignement technique ou professionnel court 4273.89328 Exerce une profession Ouvrier qualifie 7 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Oui Oui Non 2.0
1369 47 Homme 2eme cycle 1169.42226 Exerce une profession Technicien 8 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Oui Oui Oui 3.0
1370 23 Femme Enseignement technique ou professionnel court 6352.83859 Chomeur Employe 1 Non Appartenance sans pratique NA NA Non Non Non Oui Oui Non Non 4.0
1371 30 Homme Enseignement superieur y compris technique superieur 10451.17085 Exerce une profession Cadre 2 Oui Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 1.0
1372 40 Femme Enseignement technique ou professionnel long 3420.06461 Exerce une profession Technicien 5 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Non Non 2.0
1373 57 Femme Enseignement technique ou professionnel court 3404.74925 Retraite Employe 2 Non Pratiquant occasionnel NA NA Non Non Non Non Non Oui Oui 1.4
1374 63 Femme Derniere annee d’etudes primaires 5707.23890 Au foyer Employe 3 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 5.0
1375 25 Femme NA 1162.93594 Etudiant, eleve Employe 0 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Oui Non 0.9
1376 49 Homme 1er cycle 1216.36448 Exerce une profession Employe 3 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Oui Oui 1.0
1377 19 Homme NA 7514.21296 Etudiant, eleve NA 2 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Oui Oui 0.1
1378 73 Femme Enseignement technique ou professionnel court 8977.84825 Au foyer NA 0 Oui Pratiquant regulier NA NA Non Non Non Oui Non Non Non 0.0
1379 34 Femme 2eme cycle 29570.78696 Exerce une profession Employe 1 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Non Oui Oui 1.0
1380 38 Homme 2eme cycle 15116.14962 Exerce une profession Cadre 1 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 0.4
1381 19 Femme Enseignement technique ou professionnel court 6062.76946 Exerce une profession Employe 1 Non Ni croyance ni appartenance Moins important que le reste Equilibre Oui Non Non Oui Non Oui Non 4.0
1382 19 Femme NA 8881.85112 Etudiant, eleve NA 3 Non Ni croyance ni appartenance NA NA Non Non Non Oui Oui Oui Oui 2.0
1383 47 Femme N’a jamais fait d’etudes 1894.29631 Exerce une profession Ouvrier specialise 11 Non Pratiquant regulier Aussi important que le reste Satisfaction Non Non Non Non Non Non Non 2.0
1384 20 Homme NA 19356.29285 Etudiant, eleve NA 3 Oui Pratiquant regulier NA NA Non Non Non Non Non Oui Oui 2.0
1385 41 Femme 1er cycle 8829.30875 Chomeur Autre 6 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 4.0
1386 66 Homme Enseignement superieur y compris technique superieur 2824.99711 Retraite Cadre 5 Oui NSP ou NVPR NA NA Non Non Non Non Oui Oui Non 1.0
1387 34 Homme Enseignement technique ou professionnel long 3248.50561 Exerce une profession Ouvrier specialise 4 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Non 2.0
1388 42 Femme Enseignement technique ou professionnel court 1661.73796 Exerce une profession Employe 3 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Non Oui Non 2.0
1389 38 Femme Enseignement technique ou professionnel court 1545.48460 Exerce une profession Cadre 5 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Non Oui 0.7
1390 54 Femme Derniere annee d’etudes primaires 2139.56518 Au foyer Autre 10 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Non Oui 0.0
1391 58 Homme 2eme cycle 2334.02266 Retraite Profession intermediaire 2 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 4.0
1392 50 Homme Derniere annee d’etudes primaires 4895.14133 Exerce une profession Ouvrier qualifie 0 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Non Non Non 2.0
1393 70 Femme Derniere annee d’etudes primaires 3093.58563 Autre inactif Ouvrier specialise 3 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 4.0
1394 34 Homme NA 8865.78979 Etudiant, eleve NA 0 Oui Appartenance sans pratique NA NA Non Non Non Non Non Oui Non 2.0
1395 18 Homme NA 9133.39588 Etudiant, eleve NA 2 Oui Appartenance sans pratique NA NA Non Non Non Oui Oui Non Oui 1.0
1396 84 Homme 1er cycle 3844.52073 Retraite Profession intermediaire 6 Oui Pratiquant occasionnel NA NA Non Non Non Non Oui Non Non 2.0
1397 66 Femme 2eme cycle 3404.07404 Retraite Profession intermediaire 2 Oui Ni croyance ni appartenance NA NA Non Non Non Oui Oui Oui Non 0.0
1398 67 Homme Enseignement superieur y compris technique superieur 5529.21687 Retraite Cadre 0 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 0.0
1399 59 Femme Derniere annee d’etudes primaires 13775.51191 Exerce une profession NA 2 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Non Non Non 3.0
1400 45 Homme Enseignement technique ou professionnel court 1567.05846 Chomeur Ouvrier specialise 7 Oui Ni croyance ni appartenance NA NA Non Non Oui Oui Oui Oui Non 4.0
1401 40 Femme Enseignement technique ou professionnel court 5018.88111 Exerce une profession Employe 1 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Non Oui Non 2.0
1402 56 Femme 1er cycle 2302.24514 Au foyer Ouvrier qualifie 3 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 6.0
1403 21 Femme 2eme cycle 6747.15806 Chomeur NA 2 Oui Ni croyance ni appartenance NA NA Non Non Non Non Non Oui Non 5.0
1404 37 Homme Enseignement technique ou professionnel court 5620.92896 Exerce une profession Employe 2 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Oui Non Non 3.0
1405 58 Femme N’a jamais fait d’etudes 3806.47909 Retraite Employe 1 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 0.0
1406 26 Homme Enseignement technique ou professionnel long 6793.47725 Exerce une profession Ouvrier qualifie 2 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Non Oui 3.0
1407 53 Homme Enseignement technique ou professionnel court 1648.48882 Chomeur Profession intermediaire 5 Oui Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 3.0
1408 48 Femme Enseignement superieur y compris technique superieur 2239.61924 Chomeur Cadre 5 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 2.0
1409 36 Femme Enseignement technique ou professionnel court 1244.81184 Exerce une profession NA 2 Oui Pratiquant occasionnel Le plus important Equilibre Non Non Oui Oui Non Oui Non 0.1
1410 36 Homme Enseignement superieur y compris technique superieur 3615.83755 Exerce une profession Cadre 1 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Oui Oui 4.0
1411 33 Femme Enseignement technique ou professionnel court 9283.46171 Exerce une profession Employe 4 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Non Non Non 2.0
1412 87 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 3090.98358 Retraite Ouvrier specialise 3 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 3.0
1413 37 Femme Enseignement technique ou professionnel court 5166.52684 Exerce une profession NA 2 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Non Oui Oui 1.0
1414 68 Femme Derniere annee d’etudes primaires 5117.24243 Retraite Profession intermediaire 1 Oui Ni croyance ni appartenance NA NA Non Non Non Oui Non Non Oui 4.0
1415 59 Femme Derniere annee d’etudes primaires 4563.14682 Exerce une profession Employe 6 Non Appartenance sans pratique Aussi important que le reste Equilibre Non Non Oui Oui Non Oui Non 3.0
1416 54 Homme Enseignement technique ou professionnel court 1470.32043 Retraite Technicien 3 Non Ni croyance ni appartenance NA NA Non Non Non Non Oui Non Non 1.0
1417 48 Homme Enseignement technique ou professionnel court 1947.28979 Exerce une profession NA 1 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Non Non 1.0
1418 55 Femme Derniere annee d’etudes primaires 2273.04529 Autre inactif Employe 2 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 7.0
1419 47 Femme Enseignement technique ou professionnel court 5731.11668 Exerce une profession Autre 4 Oui NSP ou NVPR Moins important que le reste Satisfaction Non Non Non Non Oui Oui Non 1.0
1420 61 Homme Derniere annee d’etudes primaires 7576.04357 Retraite Ouvrier specialise 6 Oui Appartenance sans pratique NA NA Non Non Oui Non Oui Non Non 5.0
1421 27 Homme Enseignement technique ou professionnel court 5765.14614 Exerce une profession Ouvrier qualifie 3 Non Appartenance sans pratique Le plus important Satisfaction Non Non Non Non Non Non Oui 0.0
1422 34 Homme Enseignement technique ou professionnel court 5020.14424 Exerce une profession Employe 2 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Oui Oui Non 2.0
1423 53 Femme Enseignement technique ou professionnel court 1314.14456 Exerce une profession Autre 2 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Non Non Non 3.0
1424 45 Femme 2eme cycle 1902.28889 Exerce une profession Employe 2 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Non Oui Non 2.0
1425 26 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 6233.67279 Exerce une profession Ouvrier specialise 3 Ne sait pas Pratiquant regulier Peu important Insatisfaction Non Non Non Non Non Oui Non 3.0
1426 64 Femme Derniere annee d’etudes primaires 3795.37338 Retraite Technicien 2 Non NSP ou NVPR NA NA Non Non Non Oui Non Oui Non 2.0
1427 26 Femme Enseignement superieur y compris technique superieur 3986.63063 Exerce une profession Cadre 2 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 1.0
1428 35 Femme Enseignement superieur y compris technique superieur 2756.88131 Exerce une profession Employe 1 Non Pratiquant occasionnel Aussi important que le reste Insatisfaction Non Non Non Oui Oui Oui Oui 1.1
1429 42 Femme Enseignement technique ou professionnel long 4561.49562 Exerce une profession Technicien 1 Oui Appartenance sans pratique Peu important Insatisfaction Non Non Non Oui Non Oui Oui 0.4
1430 30 Homme Enseignement superieur y compris technique superieur 14805.28412 Exerce une profession Cadre 2 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Non Oui Oui 2.0
1431 38 Homme 1er cycle 6998.51046 Chomeur Ouvrier qualifie 4 Oui Appartenance sans pratique NA NA Non Non Non Oui Oui Non Oui 0.0
1432 66 Femme Derniere annee d’etudes primaires 1005.56052 Retraite Profession intermediaire 1 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 5.0
1433 51 Homme Enseignement technique ou professionnel long 5662.78790 Exerce une profession Technicien 3 Non Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Non Non Oui Non Non 1.4
1434 44 Femme N’a jamais fait d’etudes 5160.84409 Au foyer NA 6 Ne sait pas Pratiquant regulier NA NA Non Non Non Non Non Non Oui 1.0
1435 52 Homme Enseignement technique ou professionnel long 3009.35290 Exerce une profession NA 3 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Oui Oui 2.0
1436 39 Femme Enseignement superieur y compris technique superieur 10304.63997 Exerce une profession Employe 1 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Oui Non Non 2.0
1437 64 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 7957.54352 Retraite Ouvrier specialise 10 Non Appartenance sans pratique NA NA Non Non Oui Non Non Non Non 4.0
1438 54 Femme Enseignement technique ou professionnel court 4412.43775 Exerce une profession NA 2 Non Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Oui Non Non Non 3.0
1439 45 Femme Enseignement superieur y compris technique superieur 27021.94109 Au foyer NA 3 Non Pratiquant occasionnel NA NA Non Non Non Non Non Oui Oui 0.0
1440 36 Femme 1er cycle 7323.86421 Au foyer Ouvrier specialise 0 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 7.0
1441 66 Femme Derniere annee d’etudes primaires 1886.86196 Retraite Employe 2 Oui Pratiquant regulier NA NA Non Non Non Non Non Oui Non 2.0
1442 52 Homme Derniere annee d’etudes primaires 2747.41241 Exerce une profession Profession intermediaire 0 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Non Non Non 2.0
1443 54 Femme 1er cycle 3368.87646 Chomeur Employe 2 Non Appartenance sans pratique NA NA Non Non Non Oui Non Oui Oui 3.0
1444 34 Femme Enseignement superieur y compris technique superieur 3086.10218 Exerce une profession Autre 2 Non Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Non 2.0
1445 44 Femme 1er cycle 10737.42139 Exerce une profession Employe 2 Oui Appartenance sans pratique Le plus important Insatisfaction Non Non Non Oui Non Non Non 2.0
1446 49 Femme 1er cycle 592.35739 Exerce une profession Ouvrier specialise 3 Non Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Non Non Oui Non 3.0
1447 18 Femme 1er cycle 6740.33911 Exerce une profession Employe 1 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Oui Oui Oui Oui Oui 5.0
1448 35 Homme Enseignement technique ou professionnel court 3181.55455 Chomeur Ouvrier specialise 6 Oui Ni croyance ni appartenance NA NA Non Non Oui Oui Non Non Oui 0.0
1449 42 Homme Enseignement superieur y compris technique superieur 10612.10915 Exerce une profession Profession intermediaire 0 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 1.0
1450 42 Femme Enseignement superieur y compris technique superieur 1379.43238 Exerce une profession Cadre 8 Non Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 2.0
1451 45 Homme Enseignement technique ou professionnel long 11076.90257 Exerce une profession Employe 2 Oui Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Non Oui Oui Oui Non 0.4
1452 45 Homme Enseignement technique ou professionnel court 3098.49234 Exerce une profession Technicien 2 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Non Non 3.0
1453 47 Femme N’a jamais fait d’etudes 2030.81797 Exerce une profession Ouvrier specialise 8 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Non Non 2.0
1454 55 Femme Enseignement technique ou professionnel court 4064.43049 Exerce une profession Employe 4 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Non Oui Non 2.0
1455 37 Femme Enseignement superieur y compris technique superieur 4233.37037 Exerce une profession Employe 1 Oui Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Oui Oui Oui Oui 0.7
1456 40 Femme 2eme cycle 7739.94184 Exerce une profession Ouvrier specialise 1 Oui Appartenance sans pratique Peu important Equilibre Non Non Non Oui Non Non Non 3.0
1457 23 Femme NA 5169.33741 Etudiant, eleve NA 1 Non Appartenance sans pratique NA NA Non Non Non Non Non Oui Oui 0.0
1458 32 Homme Enseignement technique ou professionnel court 7188.52984 Exerce une profession Ouvrier qualifie 6 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Non 2.0
1459 48 Femme Enseignement technique ou professionnel court 8767.53823 Exerce une profession Employe 8 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Oui Non Non 0.0
1460 23 Femme 1er cycle 11354.89319 Autre inactif Ouvrier specialise 2 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 0.0
1461 71 Homme Derniere annee d’etudes primaires 4466.80440 Retraite NA 3 Non Appartenance sans pratique NA NA Non Non Oui Non Non Oui Non 2.0
1462 49 Homme Derniere annee d’etudes primaires 1617.99371 Retraite Ouvrier qualifie 3 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 2.0
1463 37 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 3824.72988 Au foyer NA 4 Non Ni croyance ni appartenance NA NA Non Non Oui Oui Non Non Non 3.0
1464 20 Homme NA 13978.83807 Etudiant, eleve NA 2 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Non Oui 0.1
1465 28 Homme Enseignement technique ou professionnel long 10658.35848 Chomeur Technicien 1 Oui Appartenance sans pratique NA NA Non Non Non Non Non Oui Oui 6.0
1466 26 Homme 1er cycle 3300.73081 Exerce une profession Ouvrier specialise 4 Non Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 2.0
1467 20 Femme NA 3564.18137 Etudiant, eleve NA 3 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Oui Oui 0.3
1468 51 Homme 1er cycle 4242.37022 Exerce une profession Ouvrier qualifie 1 Oui Ni croyance ni appartenance Le plus important Equilibre Non Non Oui Non Non Non Non 2.0
1469 32 Femme Enseignement superieur y compris technique superieur 2587.64327 Exerce une profession Employe 1 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 1.0
1470 67 Homme Enseignement superieur y compris technique superieur 1906.54632 Retraite Cadre 2 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Oui Non 3.0
1471 65 Homme Enseignement superieur y compris technique superieur 6287.49937 Retraite Cadre 1 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 1.0
1472 67 Femme Derniere annee d’etudes primaires 9402.89852 Retraite Employe 1 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 6.0
1473 48 Femme Derniere annee d’etudes primaires 7871.64520 Exerce une profession Ouvrier specialise 3 Non NSP ou NVPR Aussi important que le reste Satisfaction Non Non Non Non Non Non Non 1.0
1474 80 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 10874.67952 Retire des affaires NA 5 Non Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 0.0
1475 45 Femme Enseignement technique ou professionnel court 2449.64580 Exerce une profession Employe 7 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Oui Non Non 2.0
1476 57 Homme 2eme cycle 799.94968 Autre inactif Cadre 7 Oui Pratiquant regulier NA NA Non Non Non Non Oui Non Oui 1.0
1477 75 Homme Derniere annee d’etudes primaires 7273.59185 Retraite Ouvrier specialise 3 Oui Pratiquant regulier NA NA Non Non Oui Non Non Non Non 4.0
1478 36 Femme Enseignement technique ou professionnel court 1830.99979 Exerce une profession Ouvrier qualifie 1 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Non 3.0
1479 64 Homme Derniere annee d’etudes primaires 8201.93548 Retire des affaires NA 0 Ne sait pas Appartenance sans pratique NA NA Non Non Oui Non Oui Non Non 2.0
1480 72 Homme Enseignement technique ou professionnel long 7678.55546 Retire des affaires NA 5 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 1.0
1481 39 Homme Enseignement technique ou professionnel court 8950.32520 Exerce une profession Technicien 4 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Non Non 0.0
1482 70 Femme Enseignement superieur y compris technique superieur 4629.31294 Retraite Employe 3 Non Appartenance sans pratique NA NA Non Non Non Non Non Oui Non 2.0
1483 45 Homme Enseignement technique ou professionnel court 3107.39098 Exerce une profession Ouvrier specialise 0 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Non 4.0
1484 36 Femme Enseignement superieur y compris technique superieur 8997.35334 Exerce une profession Employe 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Non 2.0
1485 69 Femme Derniere annee d’etudes primaires 6024.44669 Retraite Ouvrier specialise 2 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 0.0
1486 66 Homme Derniere annee d’etudes primaires 8411.92320 Retraite Ouvrier specialise 3 Non Ni croyance ni appartenance NA NA Non Non Oui Oui Non Non Non 4.0
1487 49 Femme Derniere annee d’etudes primaires 4702.69996 Au foyer NA 1 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 2.0
1488 22 Femme Enseignement technique ou professionnel court 6007.17006 Au foyer Ouvrier specialise 5 Ne sait pas Ni croyance ni appartenance NA NA Non Non Oui Oui Non Non Non 5.0
1489 56 Homme 1er cycle 7389.26161 Retraite Profession intermediaire 4 Oui Pratiquant occasionnel NA NA Non Non Oui Oui Oui Non Non 1.0
1490 59 Femme Enseignement technique ou professionnel court 6172.54190 Retraite Employe 11 Oui Ni croyance ni appartenance NA NA Non Non Non Oui Non Non Non 7.0
1491 52 Femme Derniere annee d’etudes primaires 2215.35162 Autre inactif Employe 8 Oui Pratiquant occasionnel NA NA Non Non Non Non Oui Non Non 0.0
1492 32 Femme Enseignement superieur y compris technique superieur 19306.10688 Exerce une profession Employe 3 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Non Oui Oui 0.6
1493 61 Homme Enseignement technique ou professionnel court 11156.94785 Exerce une profession NA 0 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Oui Non Non Non Non 2.0
1494 43 Homme 2eme cycle 2553.26421 Exerce une profession Cadre 2 Oui Appartenance sans pratique Le plus important Satisfaction Non Non Non Non Oui Oui Oui 2.0
1495 52 Homme Enseignement technique ou professionnel court 5156.52850 Autre inactif Ouvrier qualifie 12 Oui Appartenance sans pratique NA NA Non Non Non Oui Oui Non Non 1.0
1496 30 Homme Enseignement superieur y compris technique superieur 7514.76413 Exerce une profession Cadre 2 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Non Non Non 1.0
1497 63 Femme Enseignement technique ou professionnel court 3422.80566 Retraite Employe 4 Oui Pratiquant regulier NA NA Non Non Non Oui Non Non Non 2.0
1498 57 Homme Derniere annee d’etudes primaires 6914.75303 Retraite Profession intermediaire 5 Ne sait pas NSP ou NVPR NA NA Non Non Non Oui Non Non Non 4.0
1499 68 Femme Derniere annee d’etudes primaires 5357.15447 Retraite Employe 3 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 3.0
1500 55 Homme N’a jamais fait d’etudes 204.16648 Exerce une profession Ouvrier qualifie 11 Non Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Non Oui Non Non 1.0
1501 76 Femme Derniere annee d’etudes primaires 933.83276 Au foyer Ouvrier specialise 1 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 5.0
1502 25 Homme 2eme cycle 6919.55820 Exerce une profession Ouvrier qualifie 2 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Non 1.0
1503 61 Homme Enseignement technique ou professionnel court 238.44301 Retraite Profession intermediaire 9 Oui Appartenance sans pratique NA NA Non Non Oui Oui Oui Non Oui 3.0
1504 57 Femme Enseignement technique ou professionnel court 1457.65930 Exerce une profession Employe 2 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Non Non Oui 3.0
1505 57 Femme Enseignement superieur y compris technique superieur 931.00249 Retraite Cadre 1 Oui Appartenance sans pratique NA NA Non Non Non Oui Oui Oui Non 3.0
1506 26 Homme NA 7364.66018 Etudiant, eleve NA 7 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 0.4
1507 59 Homme Enseignement technique ou professionnel court 3943.92232 Exerce une profession Ouvrier qualifie 3 Non Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Oui Oui Non Oui 2.0
1508 48 Femme Derniere annee d’etudes primaires 6575.66217 Exerce une profession Employe 8 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Non Non Non 3.0
1509 32 Femme Enseignement superieur y compris technique superieur 9819.92083 Au foyer NA 7 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 4.0
1510 63 Homme 1er cycle 11847.21598 Retire des affaires NA 4 Non Appartenance sans pratique NA NA Non Non Oui Non Oui Non Oui 2.0
1511 75 Homme Enseignement superieur y compris technique superieur 8030.46522 Retraite Cadre 1 Oui Appartenance sans pratique NA NA Non Non Non Non Non Oui Non 3.0
1512 31 Homme Enseignement technique ou professionnel court 3019.26174 Exerce une profession Ouvrier qualifie 3 Oui Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Non Oui Non Oui 0.0
1513 49 Homme Enseignement technique ou professionnel court 1867.35853 Exerce une profession Employe 5 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Oui Non Oui Non Non 3.0
1514 38 Homme Enseignement technique ou professionnel court 3459.01774 Exerce une profession Ouvrier qualifie 2 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 2.0
1515 58 Homme Enseignement technique ou professionnel court 3749.47920 Exerce une profession Employe 1 Oui Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Non Oui Oui Oui 1.0
1516 88 Femme Derniere annee d’etudes primaires 15685.58048 Retire des affaires NA 2 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 3.0
1517 88 Homme Derniere annee d’etudes primaires 7776.92847 Retraite Autre 8 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 4.0
1518 45 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 2728.39413 Autre inactif NA 3 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 4.0
1519 39 Femme Enseignement superieur y compris technique superieur 4017.44192 Exerce une profession Employe 1 Non Appartenance sans pratique Aussi important que le reste Insatisfaction Non Non Non Non Oui Non Non 3.0
1520 30 Femme Enseignement superieur y compris technique superieur 2112.24177 Exerce une profession Employe 4 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Non 4.0
1521 30 Homme Enseignement superieur y compris technique superieur 7395.90694 Exerce une profession Profession intermediaire 1 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 2.0
1522 39 Homme 2eme cycle 926.42415 Exerce une profession Technicien 0 Oui NSP ou NVPR Moins important que le reste Equilibre Non Non Non Non Oui Oui Oui 3.0
1523 57 Homme Enseignement superieur y compris technique superieur 520.48414 Exerce une profession NA 2 Oui Rejet Le plus important Equilibre Non Non Non Non Oui Oui Non 3.0
1524 37 Homme 2eme cycle 5971.95593 Exerce une profession Cadre 7 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Oui Oui 1.0
1525 37 Homme Enseignement technique ou professionnel court 9977.86613 Exerce une profession Ouvrier qualifie 1 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Oui Non 3.0
1526 22 Homme NA 4941.13681 Etudiant, eleve NA 4 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Non Oui 2.0
1527 48 Homme Enseignement technique ou professionnel court 2057.70976 Exerce une profession Cadre 5 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Oui Oui Oui 1.4
1528 51 Homme Enseignement superieur y compris technique superieur 2766.07068 Exerce une profession Cadre 2 Oui Rejet Aussi important que le reste Satisfaction Non Oui Non Non Oui Oui Oui 1.0
1529 27 Homme Derniere annee d’etudes primaires 20681.68902 Exerce une profession Ouvrier specialise 10 Non Pratiquant regulier Moins important que le reste Equilibre Non Non Non Non Non Non Non 1.0
1530 29 Homme Enseignement superieur y compris technique superieur 6388.49891 Exerce une profession Profession intermediaire 1 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 0.0
1531 52 Femme 2eme cycle 6260.74083 Exerce une profession Profession intermediaire 4 Oui Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Oui Non Non Non 2.0
1532 82 Femme Enseignement technique ou professionnel court 1250.99200 Retraite Employe 3 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Oui 3.0
1533 24 Femme NA 4629.22907 Etudiant, eleve NA 2 Oui Ni croyance ni appartenance NA NA Non Non Non Oui Non Oui Oui 1.0
1534 48 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 2070.93395 Au foyer Ouvrier qualifie 4 Oui Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 5.0
1535 35 Homme Enseignement technique ou professionnel court 2567.57328 Exerce une profession Ouvrier qualifie 3 Oui Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Non Oui Non Non 3.0
1536 37 Homme Enseignement superieur y compris technique superieur 6866.57772 Exerce une profession Autre 0 Oui Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Oui Non Oui Oui 1.0
1537 49 Femme 2eme cycle 796.86890 Au foyer Employe 4 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 4.0
1538 69 Femme Enseignement technique ou professionnel court 542.93204 Retraite Ouvrier qualifie 6 Ne sait pas Pratiquant regulier NA NA Non Non Non Non Non Non Non 10.0
1539 23 Femme 2eme cycle 5432.31536 Chomeur Employe 1 Non Rejet NA NA Non Non Non Oui Oui Oui Oui 4.0
1540 19 Femme NA 5318.27382 Etudiant, eleve NA 1 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Oui Oui 2.0
1541 34 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 10950.07620 Exerce une profession NA 10 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Oui Non Non 3.0
1542 93 Femme Derniere annee d’etudes primaires 7107.84060 Retire des affaires NA 7 Non Pratiquant occasionnel NA NA Non Non Non Non Non Oui Non 3.0
1543 44 Homme Enseignement technique ou professionnel court 5308.37575 Exerce une profession Ouvrier qualifie 2 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Oui Non Oui Non Non 2.0
1544 43 Femme Enseignement superieur y compris technique superieur 1274.61612 Exerce une profession NA 2 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Non Oui Oui 1.0
1545 27 Femme 1er cycle 853.21886 Chomeur Ouvrier specialise 9 Non Appartenance sans pratique NA NA Non Non Non Oui Oui Non Non 1.0
1546 53 Homme 1er cycle 7150.07207 Exerce une profession Ouvrier qualifie 4 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Oui Non Non 0.0
1547 50 Femme Enseignement superieur y compris technique superieur 1914.83237 Chomeur Employe 13 Ne sait pas Pratiquant occasionnel NA NA Non Non Non Oui Oui Oui Oui 6.0
1548 55 Homme Enseignement technique ou professionnel long 14191.39108 Exerce une profession Cadre 4 Non Ni croyance ni appartenance Peu important Insatisfaction Non Non Non Non Non Non Non 1.0
1549 77 Femme 1er cycle 1369.19178 Retraite Ouvrier qualifie 2 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 3.0
1550 22 Homme NA 9457.08596 Etudiant, eleve NA 6 Oui Appartenance sans pratique NA NA Non Non Non Non Non Oui Oui 0.0
1551 68 Femme Derniere annee d’etudes primaires 2897.27634 Retraite Ouvrier specialise 2 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 6.0
1552 34 Homme Enseignement technique ou professionnel court 2485.84216 Exerce une profession Employe 3 Oui Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Oui Oui Non Oui 0.0
1553 75 Homme Derniere annee d’etudes primaires 9568.31058 Retire des affaires NA 3 Non Appartenance sans pratique NA NA Non Non Oui Non Non Non Non 3.0
1554 36 Homme Enseignement superieur y compris technique superieur 704.50182 Exerce une profession Cadre 4 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Non Oui Oui 3.0
1555 52 Femme Enseignement technique ou professionnel court 4276.02236 Exerce une profession Employe 3 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Oui Non Oui 1.0
1556 33 Femme Enseignement superieur y compris technique superieur 5535.72536 Exerce une profession Cadre 1 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 0.6
1557 43 Homme Enseignement superieur y compris technique superieur 2248.39503 Exerce une profession Cadre 0 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 1.0
1558 57 Femme Enseignement technique ou professionnel court 2608.39965 Exerce une profession Employe 2 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Non Non Non 1.0
1559 19 Homme NA 9262.37674 Etudiant, eleve NA 3 Oui Pratiquant regulier NA NA Non Non Non Oui Non Oui Oui 1.0
1560 23 Homme Enseignement superieur y compris technique superieur 11741.00184 Exerce une profession Employe 0 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Oui Oui Non Oui Oui 0.1
1561 29 Homme Enseignement technique ou professionnel court 13267.53678 Exerce une profession Profession intermediaire 1 Non Pratiquant occasionnel Aussi important que le reste Equilibre Non Non Non Oui Oui Non Oui 3.0
1562 28 Homme 2eme cycle 3884.22397 Exerce une profession Employe 8 Oui Ni croyance ni appartenance Aussi important que le reste Insatisfaction Non Non Non Non Non Non Non 0.4
1563 36 Femme Enseignement superieur y compris technique superieur 1725.22536 Exerce une profession Employe 1 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Oui Non Oui Oui Oui Non 2.0
1564 79 Femme Enseignement technique ou professionnel court 3153.03154 Retraite Ouvrier specialise 9 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 4.0
1565 45 Femme Enseignement superieur y compris technique superieur 2163.64209 Chomeur Employe 4 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Oui 1.0
1566 39 Homme NA 8793.52511 Exerce une profession Employe 6 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Oui Non Oui 3.0
1567 45 Femme 2eme cycle 4771.02387 Exerce une profession Employe 6 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Non Non Non 2.0
1568 26 Homme Enseignement technique ou professionnel court 6925.62413 Chomeur Ouvrier specialise 3 Oui Ni croyance ni appartenance NA NA Non Non Non Non Oui Oui Oui 0.0
1569 70 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 2651.40485 Autre inactif Employe 11 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 2.0
1570 29 Homme Enseignement superieur y compris technique superieur 8410.55464 Exerce une profession NA 1 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Non Oui Oui 0.0
1571 50 Femme Enseignement technique ou professionnel court 898.65363 Exerce une profession Autre 1 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Oui Non 2.0
1572 44 Homme 1er cycle 8082.93717 Exerce une profession Ouvrier specialise 5 Oui Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Non Oui Oui Non Non 5.0
1573 78 Femme Enseignement superieur y compris technique superieur 12855.25096 Retraite Cadre 0 Non Pratiquant occasionnel NA NA Non Non Non Non Non Oui Non 2.0
1574 52 Femme Enseignement technique ou professionnel court 616.88703 Exerce une profession Employe 4 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Oui Non Non 2.0
1575 78 Femme Derniere annee d’etudes primaires 868.83840 Au foyer Ouvrier qualifie 1 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 8.0
1576 32 Homme 1er cycle 3444.37391 Exerce une profession Ouvrier qualifie 3 Oui Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Oui Non Oui Oui Oui 2.0
1577 54 Homme 2eme cycle 662.80449 Exerce une profession Profession intermediaire 3 Non Ni croyance ni appartenance Peu important Equilibre Non Non Non Non Oui Non Oui 3.0
1578 30 Homme Enseignement superieur y compris technique superieur 7367.10529 Exerce une profession Employe 6 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Non 1.0
1579 41 Femme Enseignement superieur y compris technique superieur 5323.88100 Exerce une profession Cadre 1 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Oui Non Oui 0.0
1580 27 Homme Enseignement superieur y compris technique superieur 7337.74030 Exerce une profession Cadre 1 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Oui Non Non Oui Oui 2.0
1581 54 Femme Enseignement technique ou professionnel court 12246.10604 Au foyer Ouvrier specialise 3 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 1.0
1582 54 Homme Derniere annee d’etudes primaires 2987.43234 Chomeur Cadre 7 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 4.0
1583 48 Homme 1er cycle 7838.57762 Exerce une profession Profession intermediaire 2 Non Pratiquant occasionnel Moins important que le reste Insatisfaction Non Non Oui Oui Non Oui Non 2.0
1584 26 Femme Enseignement superieur y compris technique superieur 9183.73557 Exerce une profession Employe 1 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 2.0
1585 29 Femme Enseignement superieur y compris technique superieur 3072.79663 Exerce une profession Profession intermediaire 4 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Oui Non Oui 3.0
1586 61 Homme Enseignement superieur y compris technique superieur 4625.11369 Retraite Cadre 5 Non Pratiquant regulier NA NA Non Non Non Non Oui Oui Oui 2.0
1587 53 Femme Enseignement technique ou professionnel court 1540.21018 Exerce une profession NA 5 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Oui Non Non 3.0
1588 67 Homme Derniere annee d’etudes primaires 1278.01451 Retraite Ouvrier qualifie 1 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 3.0
1589 52 Femme Derniere annee d’etudes primaires 3450.46327 Exerce une profession Employe 9 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Non Non Non 1.0
1590 64 Homme Derniere annee d’etudes primaires 3524.83932 Retraite Ouvrier qualifie 3 Non Appartenance sans pratique NA NA Non Non Oui Non Non Non Oui 3.0
1591 82 Femme Enseignement technique ou professionnel court 4296.29193 Retraite Ouvrier qualifie 4 Ne sait pas Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 4.0
1592 74 Homme Enseignement technique ou professionnel court 4829.14022 Retraite Employe 0 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 4.0
1593 36 Homme Enseignement technique ou professionnel court 443.17604 Exerce une profession Ouvrier qualifie 4 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Non Oui 1.0
1594 30 Homme 2eme cycle 6781.55643 Exerce une profession Employe 4 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Non 2.0
1595 22 Homme NA 9262.37674 Etudiant, eleve NA 1 Oui Rejet NA NA Non Non Non Non Non Oui Oui 3.0
1596 70 Homme 2eme cycle 11477.96272 Retraite Profession intermediaire 5 Non Appartenance sans pratique NA NA Non Non Non Non Non Oui Oui 3.0
1597 39 Femme Enseignement technique ou professionnel court 736.86436 Exerce une profession Employe 5 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Non Non Non 4.0
1598 34 Femme Enseignement technique ou professionnel long 3458.28997 Exerce une profession Employe 0 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Non Non Oui 3.0
1599 77 Homme Derniere annee d’etudes primaires 4546.91432 Retraite NA 0 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 2.0
1600 18 Femme NA 4314.26803 Exerce une profession Ouvrier specialise 2 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Non Oui Oui 2.0
1601 47 Homme Enseignement superieur y compris technique superieur 4131.51144 Exerce une profession Cadre 1 Oui Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Non Non Non Oui Non 2.0
1602 38 Femme Enseignement superieur y compris technique superieur 5538.19479 Exerce une profession Employe 0 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Non Oui Non 2.0
1603 34 Femme 1er cycle 1050.28418 Exerce une profession Employe 22 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Non Oui Non 2.0
1604 55 Homme Enseignement technique ou professionnel court 11440.85272 Exerce une profession NA 3 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Oui Oui Oui Non Non 2.0
1605 39 Femme Enseignement technique ou professionnel court 10365.59071 Au foyer Employe 2 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 3.0
1606 81 Homme 1er cycle 4492.99836 Retraite Profession intermediaire 0 Oui Ni croyance ni appartenance NA NA Non Non Non Non Oui Non Non 3.0
1607 19 Homme Enseignement technique ou professionnel court 1760.29569 Chomeur Employe 2 Oui Appartenance sans pratique NA NA Non Non Non Non Non Oui Oui 4.0
1608 20 Homme NA 22870.42151 Etudiant, eleve Ouvrier qualifie 1 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Non Oui 1.0
1609 39 Homme Enseignement superieur y compris technique superieur 6721.53253 Exerce une profession Cadre 0 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Oui Non Non Non Oui 2.0
1610 34 Femme Enseignement superieur y compris technique superieur 7052.14636 Au foyer Autre 1 Oui Pratiquant occasionnel NA NA Non Non Non Non Oui Oui Oui 2.0
1611 53 Femme 2eme cycle 1947.28316 Chomeur Employe 2 Oui Pratiquant regulier NA NA Non Non Non Non Non Oui Non 1.0
1612 47 Femme Derniere annee d’etudes primaires 4898.86822 Chomeur Employe 4 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 3.0
1613 56 Homme Enseignement technique ou professionnel long 7301.08768 Exerce une profession Profession intermediaire 0 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Non Oui 2.0
1614 75 Femme 2eme cycle 2768.09230 Retraite Technicien 1 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 2.0
1615 74 Homme 2eme cycle 5878.79339 Retraite Cadre 1 Non Rejet NA NA Non Non Non Non Non Non Non 5.0
1616 53 Femme Enseignement superieur y compris technique superieur 17118.49003 Exerce une profession Cadre 1 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Non Oui Oui 2.0
1617 57 Femme Derniere annee d’etudes primaires 3186.46972 Au foyer Ouvrier qualifie 12 Non Pratiquant regulier NA NA Non Non Non Oui Oui Non Oui 4.0
1618 37 Femme Enseignement technique ou professionnel court 3135.90648 Exerce une profession Employe 2 Oui Ni croyance ni appartenance Moins important que le reste Insatisfaction Non Non Non Non Non Oui Oui 0.0
1619 25 Homme NA 3767.83271 Exerce une profession Employe 5 Oui Pratiquant regulier Moins important que le reste Equilibre Non Non Non Non Non Non Oui 2.0
1620 22 Homme Enseignement technique ou professionnel court 8757.76734 Chomeur Ouvrier specialise 1 Non Ni croyance ni appartenance NA NA Non Non Non Non Oui Oui Oui 2.0
1621 62 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 2600.59060 Retraite Ouvrier qualifie 4 Non Pratiquant regulier NA NA Non Non Non Non Oui Non Non 10.0
1622 56 Femme 1er cycle 8233.92116 Au foyer NA 2 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 3.0
1623 54 Femme 1er cycle 2805.95796 Autre inactif Ouvrier specialise 5 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 2.0
1624 46 Femme 1er cycle 1517.30121 Chomeur Employe 3 Oui Ni croyance ni appartenance NA NA Non Non Non Oui Oui Non Non 2.0
1625 34 Femme Enseignement superieur y compris technique superieur 8200.15517 Exerce une profession Technicien 4 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Non Oui 0.0
1626 57 Femme 1er cycle 3201.69368 Au foyer Ouvrier qualifie 2 Non Pratiquant occasionnel NA NA Non Non Non Non Oui Oui Non 0.0
1627 21 Homme NA 10772.84994 Etudiant, eleve NA 2 Oui Ni croyance ni appartenance NA NA Non Non Non Non Non Oui Oui 2.9
1628 68 Homme Enseignement superieur y compris technique superieur 4872.16258 Retraite Cadre 3 Oui Appartenance sans pratique NA NA Non Non Non Non Non Oui Non 1.0
1629 27 Femme Enseignement superieur y compris technique superieur 2400.09786 Exerce une profession Autre 0 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Non 0.1
1630 48 Homme Enseignement technique ou professionnel court 1572.63005 Exerce une profession Ouvrier qualifie 3 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Oui Non 3.0
1631 37 Femme Enseignement superieur y compris technique superieur 5713.78178 Exerce une profession Employe 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Non 4.0
1632 48 Homme Enseignement technique ou professionnel court 6277.85110 Exerce une profession Technicien 2 Non Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Non Non Non Non Non 0.0
1633 72 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 2114.79233 Au foyer NA 2 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 2.0
1634 19 Homme NA 7526.51664 Etudiant, eleve NA 2 Non Ni croyance ni appartenance NA NA Non Non Non Oui Non Oui Oui 1.0
1635 60 Femme Enseignement technique ou professionnel long 8248.67622 Exerce une profession Employe 0 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Non Non Non 3.0
1636 71 Homme Derniere annee d’etudes primaires 1965.50128 Retraite Ouvrier qualifie 1 Oui Pratiquant regulier NA NA Non Non Non Oui Oui Non Non 3.0
1637 31 Homme 1er cycle 29548.78954 Exerce une profession Employe 6 Ne sait pas Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Non Non Non 4.0
1638 33 Homme Enseignement technique ou professionnel court 8851.86979 Exerce une profession NA 2 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Non Oui Oui 2.0
1639 73 Femme Enseignement technique ou professionnel court 5858.79439 Retraite Employe 1 Oui Pratiquant occasionnel NA NA Non Non Non Non Oui Oui Non 2.0
1640 21 Homme NA 3026.57217 Etudiant, eleve NA 3 Non Pratiquant regulier NA NA Non Non Non Non Non Non Oui 1.4
1641 23 Homme Enseignement technique ou professionnel long 17764.99670 Exerce une profession Ouvrier qualifie 2 Oui Ni croyance ni appartenance Aussi important que le reste Insatisfaction Non Non Oui Oui Oui Oui Oui 6.0
1642 52 Femme Enseignement technique ou professionnel court 6749.68661 Exerce une profession Ouvrier specialise 1 Non Pratiquant regulier Peu important Insatisfaction Non Non Non Oui Non Oui Oui 3.0
1643 57 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 981.96368 Exerce une profession Employe 7 Oui Rejet Moins important que le reste Insatisfaction Non Non Non Oui Oui Non Oui 4.0
1644 64 Femme Derniere annee d’etudes primaires 4334.91020 Retraite Employe 4 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 8.0
1645 21 Homme NA 7093.55382 Etudiant, eleve NA 2 Non Ni croyance ni appartenance NA NA Non Non Oui Oui Oui Oui Oui 2.0
1646 23 Homme Enseignement technique ou professionnel court 10725.84450 Exerce une profession Ouvrier specialise 4 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Oui Non Non 0.0
1647 25 Femme NA 7147.28264 Exerce une profession Autre 1 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 2.0
1648 27 Femme Enseignement superieur y compris technique superieur 10019.91670 Exerce une profession Employe 1 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Oui Non Oui Oui Oui Oui 2.0
1649 44 Femme Enseignement technique ou professionnel court 3109.64809 Exerce une profession Employe 2 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Oui Oui Non 3.0
1650 42 Femme Enseignement technique ou professionnel court 2549.26025 Exerce une profession Employe 5 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Non Oui Non 2.0
1651 30 Homme Enseignement superieur y compris technique superieur 5310.26295 Exerce une profession Technicien 1 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Oui Oui 1.0
1652 41 Homme Enseignement superieur y compris technique superieur 5303.34582 Exerce une profession Employe 2 Non Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Oui Oui Oui Oui 3.0
1653 40 Femme Enseignement superieur y compris technique superieur 8906.30907 Exerce une profession Cadre 1 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Non Non Oui 3.0
1654 41 Homme Enseignement technique ou professionnel court 9947.85164 Exerce une profession Ouvrier qualifie 5 Oui Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Non Oui Oui Oui 4.0
1655 40 Femme Enseignement technique ou professionnel court 5801.79640 Exerce une profession Employe 2 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Non Non Non 4.0
1656 39 Homme Enseignement superieur y compris technique superieur 92.93637 Exerce une profession Cadre 2 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Oui Oui Oui 1.0
1657 48 Femme Enseignement technique ou professionnel court 1113.24521 Exerce une profession Employe 3 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Oui Non Non Oui Non 2.0
1658 52 Femme 1er cycle 9854.04732 Exerce une profession Ouvrier specialise 4 Non Rejet Peu important Equilibre Non Non Non Oui Non Non Non 3.0
1659 50 Femme 2eme cycle 5840.41730 Exerce une profession Autre 4 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Non Non Oui 0.6
1660 21 Homme NA 9262.37674 Etudiant, eleve NA 1 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Oui Oui 2.0
1661 20 Homme 2eme cycle 3342.89258 Exerce une profession Ouvrier specialise 5 Oui Pratiquant regulier Moins important que le reste Insatisfaction Non Non Non Oui Oui Oui Oui 2.0
1662 53 Homme Enseignement superieur y compris technique superieur 2789.15147 Exerce une profession Cadre 3 Oui Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Non Non Oui Non Oui 0.0
1663 61 Homme Enseignement superieur y compris technique superieur 7993.74541 Retraite Cadre 2 Oui Appartenance sans pratique NA NA Non Non Oui Non Non Oui Oui 4.0
1664 88 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 1055.54186 Retraite Employe 4 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 2.0
1665 23 Femme Enseignement superieur y compris technique superieur 5429.59491 Exerce une profession Employe 2 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Oui Non Non Oui Non Non Non 3.0
1666 86 Femme 1er cycle 6382.72848 Au foyer Cadre 0 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 3.0
1667 74 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 1035.61633 Retraite Employe 3 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 3.0
1668 69 Homme Enseignement technique ou professionnel court 2145.95617 Retire des affaires NA 2 Non Pratiquant occasionnel NA NA Non Non Non Non Oui Non Non 3.0
1669 44 Femme Enseignement technique ou professionnel court 1876.79632 Exerce une profession Ouvrier qualifie 1 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 0.0
1670 35 Homme Enseignement technique ou professionnel long 8366.49157 Exerce une profession Cadre 3 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Oui Oui Oui 2.0
1671 73 Homme Enseignement superieur y compris technique superieur 2438.01714 Retraite Cadre 4 Oui Pratiquant occasionnel NA NA Non Non Non Oui Oui Non Oui 2.0
1672 39 Homme Enseignement superieur y compris technique superieur 5413.92256 Exerce une profession Profession intermediaire 1 Oui NSP ou NVPR Moins important que le reste Satisfaction Non Non Non Non Non Non Non 1.7
1673 48 Femme Enseignement superieur y compris technique superieur 453.96878 Exerce une profession Profession intermediaire 4 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Oui Non Non Non Oui Oui 1.0
1674 42 Femme Enseignement superieur y compris technique superieur 772.04823 Exerce une profession Cadre 2 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Oui Oui Non 0.0
1675 56 Femme Enseignement technique ou professionnel court 2239.40771 Exerce une profession Employe 3 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Non Non Oui 3.0
1676 40 Homme 2eme cycle 12316.73032 Exerce une profession Employe 1 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Oui Oui Non 2.0
1677 40 Femme 1er cycle 855.29199 Exerce une profession Employe 9 Non Pratiquant regulier Aussi important que le reste Equilibre Non Non Non Non Non Non Non 1.0
1678 58 Homme Enseignement superieur y compris technique superieur 473.01688 Exerce une profession Cadre 2 Oui Rejet Moins important que le reste Satisfaction Non Non Oui Oui Oui Oui Oui 1.0
1679 80 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 5568.52642 Retraite NA 2 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 0.0
1680 76 Homme N’a jamais fait d’etudes 852.41196 Retraite Ouvrier specialise 7 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 3.0
1681 63 Homme NA 4836.13931 Retraite Autre 1 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Non Oui 1.0
1682 43 Homme Enseignement superieur y compris technique superieur 7788.15964 Exerce une profession Cadre 2 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Oui Non 3.0
1683 74 Femme Derniere annee d’etudes primaires 12265.60802 Retire des affaires NA 1 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 3.0
1684 55 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 1362.84771 Autre inactif Profession intermediaire 3 Oui Appartenance sans pratique NA NA Non Non Oui Oui Non Non Non 10.0
1685 35 Femme Enseignement technique ou professionnel court 324.16574 Au foyer Employe 2 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 10.0
1686 40 Femme Enseignement superieur y compris technique superieur 2009.70977 Chomeur Employe 1 Oui Appartenance sans pratique NA NA Non Non Non Oui Oui Oui Oui 0.0
1687 51 Femme Enseignement technique ou professionnel court 1596.04757 Exerce une profession Employe 4 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Oui Non Non 4.0
1688 67 Femme 1er cycle 15483.23390 Retraite Cadre 0 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 5.0
1689 19 Homme NA 10727.56246 Etudiant, eleve NA 0 Oui Pratiquant regulier NA NA Non Non Non Oui Non Oui Oui 0.3
1690 27 Homme Enseignement superieur y compris technique superieur 18639.52145 Exerce une profession Ouvrier specialise 2 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Non Non 2.0
1691 89 Homme Derniere annee d’etudes primaires 3486.46615 Retire des affaires NA 6 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 3.0
1692 62 Homme Enseignement superieur y compris technique superieur 3276.32672 Retraite Cadre 1 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 2.0
1693 45 Homme Enseignement technique ou professionnel court 7324.84369 Exerce une profession Profession intermediaire 4 Oui Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Oui Oui Oui Oui 1.0
1694 33 Femme Enseignement technique ou professionnel court 8601.02300 Exerce une profession Employe 4 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Oui Oui Non Oui 0.7
1695 37 Homme Enseignement superieur y compris technique superieur 7308.50430 Exerce une profession Cadre 2 Non Ni croyance ni appartenance Aussi important que le reste Insatisfaction Non Oui Non Oui Oui Oui Oui 1.0
1696 26 Femme 1er cycle 4099.14242 Exerce une profession Employe 4 Non Ni croyance ni appartenance Moins important que le reste Insatisfaction Non Non Non Non Oui Oui Non 1.0
1697 74 Femme Derniere annee d’etudes primaires 5416.05125 Retraite Employe 0 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 5.0
1698 59 Homme Enseignement technique ou professionnel court 2866.96656 Chomeur Profession intermediaire 5 Oui Appartenance sans pratique NA NA Non Non Non Oui Oui Non Non 4.0
1699 47 Femme Enseignement superieur y compris technique superieur 842.08539 Exerce une profession Cadre 1 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Oui Non 1.0
1700 54 Femme Derniere annee d’etudes primaires 1830.87950 Exerce une profession Ouvrier specialise 6 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Oui Non Non 2.0
1701 36 Homme Enseignement superieur y compris technique superieur 2088.89940 Exerce une profession Cadre 2 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Non Oui Oui 2.0
1702 28 Femme Enseignement technique ou professionnel court 11202.98847 Exerce une profession Employe 2 Non Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Non Oui Non Non Non 3.0
1703 30 Femme Enseignement technique ou professionnel court 12081.02626 Au foyer Employe 3 Non NSP ou NVPR NA NA Non Non Non Oui Oui Oui Oui 2.0
1704 60 Homme Enseignement superieur y compris technique superieur 2282.05819 Exerce une profession Cadre 3 Oui Pratiquant regulier Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 0.9
1705 43 Femme Enseignement technique ou professionnel long 11347.67529 Exerce une profession Technicien 1 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Oui Non Non 0.0
1706 44 Homme Enseignement technique ou professionnel court 5927.08888 Exerce une profession Ouvrier qualifie 2 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Non Oui Non 0.3
1707 80 Femme 2eme cycle 12533.83881 Retraite Cadre 2 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Non Non 0.0
1708 47 Femme 1er cycle 4885.31123 Chomeur Employe 1 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 0.0
1709 35 Femme Enseignement technique ou professionnel long 833.93771 Exerce une profession Employe 6 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Oui Non 3.0
1710 23 Femme 1er cycle 6905.59807 Chomeur Employe 6 Non Ni croyance ni appartenance NA NA Oui Non Non Non Non Oui Non 4.0
1711 55 Homme 2eme cycle 1692.64166 Exerce une profession Employe 9 Oui Rejet Aussi important que le reste Satisfaction Non Non Oui Non Oui Non Non 2.0
1712 66 Femme Derniere annee d’etudes primaires 6684.81652 Retraite Employe 3 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 4.0
1713 39 Homme Enseignement technique ou professionnel court 2374.38639 Exerce une profession Ouvrier qualifie 5 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Oui Non Oui 1.0
1714 49 Femme Enseignement superieur y compris technique superieur 1525.07136 Exerce une profession Cadre 4 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 1.0
1715 62 Homme Enseignement superieur y compris technique superieur 11348.08373 Retraite Cadre 3 Non Appartenance sans pratique NA NA Non Non Oui Non Non Non Non 4.0
1716 26 Femme Enseignement superieur y compris technique superieur 9438.65325 Au foyer Employe 5 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 7.0
1717 45 Homme Enseignement technique ou professionnel court 2164.26775 Exerce une profession Profession intermediaire 5 Oui Ni croyance ni appartenance Aussi important que le reste Insatisfaction Non Non Non Oui Oui Non Non 2.0
1718 54 Femme Derniere annee d’etudes primaires 5382.16545 Exerce une profession Employe 6 Oui Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Oui Non Non Non 1.0
1719 56 Femme 1er cycle 1938.48362 Au foyer NA 4 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 3.0
1720 74 Femme Enseignement technique ou professionnel court 4215.07751 Retraite Ouvrier specialise 1 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 5.0
1721 78 Femme Enseignement technique ou professionnel court 6889.07086 Retraite Employe 0 Oui Pratiquant regulier NA NA Non Non Non Non Non Oui Oui 3.0
1722 52 Femme 2eme cycle 4355.15419 Exerce une profession Technicien 3 Non Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Non Oui Non Non 2.0
1723 40 Femme Derniere annee d’etudes primaires 2631.81488 Au foyer Employe 7 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 2.0
1724 36 Homme Enseignement technique ou professionnel court 13048.65917 Exerce une profession Ouvrier specialise 2 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Oui Non Non 0.0
1725 45 Homme Enseignement technique ou professionnel court 627.53934 Exerce une profession Cadre 3 Non Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Oui Non Non Non 0.4
1726 76 Homme Enseignement superieur y compris technique superieur 3464.04622 Retire des affaires NA 1 Oui Pratiquant regulier NA NA Non Non Non Non Oui Non Non 3.0
1727 69 Homme Derniere annee d’etudes primaires 5114.64669 Retraite Ouvrier specialise 0 Ne sait pas Appartenance sans pratique NA NA Non Non Non Non Non Non Non 10.0
1728 44 Homme N’a jamais fait d’etudes 3240.21397 Autre inactif NA 7 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 4.0
1729 31 Femme Enseignement technique ou professionnel long 11305.21743 Exerce une profession Ouvrier specialise 0 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 1.0
1730 79 Homme Derniere annee d’etudes primaires 2641.19973 Retraite Profession intermediaire 5 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 6.0
1731 57 Femme Derniere annee d’etudes primaires 4875.17709 Exerce une profession Ouvrier qualifie 1 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Non Non Non 2.0
1732 55 Homme Enseignement technique ou professionnel court 8222.27349 Exerce une profession Ouvrier qualifie 2 Non Ni croyance ni appartenance Peu important Equilibre Non Non Oui Non Oui Non Non 2.0
1733 50 Femme Enseignement technique ou professionnel court 10453.81230 Exerce une profession Employe 2 Non Appartenance sans pratique Aussi important que le reste Insatisfaction Non Non Non Non Oui Oui Non 6.0
1734 49 Homme Enseignement technique ou professionnel court 7567.34821 Exerce une profession Ouvrier qualifie 3 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Oui Oui Non 3.0
1735 65 Homme 1er cycle 6883.60042 Autre inactif Ouvrier qualifie 1 Oui Ni croyance ni appartenance NA NA Non Non Non Non Oui Non Non 3.0
1736 60 Femme 2eme cycle 814.73085 Retraite Profession intermediaire 1 Non Pratiquant regulier NA NA Non Non Oui Non Non Oui Oui 3.0
1737 21 Homme NA 9262.37674 Etudiant, eleve NA 1 Non Ni croyance ni appartenance NA NA Non Non Non Oui Oui Oui Oui 1.4
1738 52 Femme 1er cycle 4834.76135 Exerce une profession Employe 0 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Non Oui Oui 0.0
1739 62 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 936.02464 Retraite Ouvrier qualifie 8 Non Pratiquant occasionnel NA NA Non Non Non Non Oui Non Non 4.0
1740 70 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 2718.19378 Retraite Ouvrier qualifie 1 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Oui 1.0
1741 73 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 1482.91188 Retraite Ouvrier specialise 2 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 2.0
1742 31 Homme Enseignement technique ou professionnel court 11752.96203 Exerce une profession Ouvrier qualifie 1 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Non Oui 2.0
1743 25 Femme Enseignement superieur y compris technique superieur 6168.50167 Exerce une profession Profession intermediaire 1 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Non Oui 2.0
1744 64 Homme Enseignement technique ou professionnel court 1262.67675 Retraite Ouvrier qualifie 1 Non Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 6.0
1745 24 Homme Enseignement technique ou professionnel court 4831.16493 Chomeur Ouvrier specialise 8 Oui Ni croyance ni appartenance NA NA Non Non Oui Oui Oui Non Non 2.0
1746 72 Femme 1er cycle 10643.09577 Retire des affaires NA 2 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 4.0
1747 37 Femme 2eme cycle 5833.68803 Exerce une profession Employe 6 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Non Oui Oui 0.3
1748 48 Femme Derniere annee d’etudes primaires 4212.07679 Exerce une profession Ouvrier qualifie 8 Non Appartenance sans pratique Peu important Equilibre Non Non Non Oui Non Oui Non 2.0
1749 58 Femme Enseignement superieur y compris technique superieur 6088.58903 Au foyer NA 3 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Oui Non 2.0
1750 32 Femme 1er cycle 7818.23035 Chomeur Ouvrier specialise 7 Non NSP ou NVPR NA NA Non Non Non Oui Non Non Non 2.0
1751 47 Femme Enseignement superieur y compris technique superieur 4228.22664 Exerce une profession Autre 2 Non Pratiquant regulier Moins important que le reste Satisfaction Non Oui Non Non Oui Oui Oui 0.7
1752 50 Femme Derniere annee d’etudes primaires 4100.45860 Exerce une profession Employe 4 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Non 2.0
1753 38 Homme Enseignement technique ou professionnel court 7515.24410 Exerce une profession Ouvrier qualifie 5 Oui Pratiquant regulier Moins important que le reste Equilibre Non Non Non Non Oui Non Oui 4.0
1754 43 Femme 1er cycle 7534.40032 Exerce une profession Employe 2 Non Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Non Non Non Non Non 1.0
1755 55 Homme Derniere annee d’etudes primaires 2348.47064 Chomeur Ouvrier qualifie 2 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 2.0
1756 24 Femme Enseignement technique ou professionnel long 5276.45519 Chomeur Employe 0 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 6.0
1757 62 Femme Enseignement superieur y compris technique superieur 5117.24243 Retraite Cadre 2 Oui Pratiquant regulier NA NA Non Non Non Oui Oui Oui Non 1.0
1758 45 Homme Enseignement superieur y compris technique superieur 9530.08871 Exerce une profession Technicien 0 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Oui Non Oui Oui Oui 1.4
1759 44 Homme 1er cycle 2064.63151 Exerce une profession Ouvrier qualifie 4 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Non Non Oui 6.0
1760 55 Femme Derniere annee d’etudes primaires 981.80945 Chomeur Technicien 4 Oui Pratiquant occasionnel NA NA Non Non Non Oui Oui Non Non 3.0
1761 34 Femme Enseignement technique ou professionnel court 3210.84753 Au foyer NA 7 Ne sait pas Rejet NA NA Non Non Oui Oui Non Oui Non 11.0
1762 30 Femme Enseignement superieur y compris technique superieur 11094.39188 Exerce une profession Employe 5 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Non Non Oui 3.0
1763 25 Femme Enseignement technique ou professionnel court 1803.71425 Exerce une profession Employe 4 Non Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Non Non Oui Non 2.0
1764 47 Homme Enseignement technique ou professionnel court 5303.34582 Exerce une profession Ouvrier qualifie 10 Oui Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Non Non Non Oui Non 0.0
1765 28 Femme Enseignement superieur y compris technique superieur 4496.70072 Exerce une profession Profession intermediaire 1 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Non Oui Oui 2.0
1766 43 Homme 2eme cycle 1522.94751 Exerce une profession Technicien 5 Non Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Non Oui Oui Oui 3.0
1767 90 Femme Derniere annee d’etudes primaires 12265.60802 Retire des affaires NA 2 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 3.0
1768 24 Femme NA 10338.67483 Etudiant, eleve NA 0 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Oui Oui 2.0
1769 51 Femme Derniere annee d’etudes primaires 3555.51775 Exerce une profession Ouvrier qualifie 7 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Non Non Non 2.0
1770 41 Femme Enseignement technique ou professionnel court 3901.40356 Exerce une profession Employe 3 Non Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Oui Non Oui Oui 2.0
1771 54 Femme Enseignement superieur y compris technique superieur 2478.11428 Exerce une profession Cadre 2 Oui Ni croyance ni appartenance Moins important que le reste Insatisfaction Non Oui Non Non Oui Oui Oui 2.0
1772 41 Femme Enseignement superieur y compris technique superieur 1248.37129 Exerce une profession Employe 3 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Oui Non 1.0
1773 52 Homme Derniere annee d’etudes primaires 6626.08984 Exerce une profession Ouvrier qualifie 0 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Oui Non Non 0.0
1774 18 Homme NA 8833.99839 Etudiant, eleve NA 1 Non Appartenance sans pratique NA NA Non Non Non Non Non Oui Oui 4.0
1775 44 Femme Enseignement superieur y compris technique superieur 1617.22137 Exerce une profession Profession intermediaire 4 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Non Non Oui 0.0
1776 65 Femme Derniere annee d’etudes primaires 6864.25787 Au foyer Employe 6 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 6.0
1777 37 Femme Enseignement superieur y compris technique superieur 2997.05954 Exerce une profession NA 5 Non Pratiquant regulier Moins important que le reste Satisfaction Non Oui Non Oui Non Oui Oui 1.4
1778 45 Homme Enseignement superieur y compris technique superieur 4018.76869 Exerce une profession Autre 2 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Oui Non 2.0
1779 36 Femme Enseignement technique ou professionnel court 552.61185 Exerce une profession Employe 6 Oui Pratiquant occasionnel Peu important Satisfaction Non Non Oui Oui Oui Non Non 3.0
1780 46 Homme Enseignement technique ou professionnel court 9279.64972 Exerce une profession Profession intermediaire 1 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Oui Oui Oui Oui Oui 0.6
1781 29 Femme 1er cycle 872.36834 Exerce une profession Ouvrier specialise 3 Non Appartenance sans pratique Le plus important Satisfaction Non Non Non Oui Oui Oui Oui 0.0
1782 42 Homme Enseignement technique ou professionnel court 7282.84175 Exerce une profession NA 5 Non Pratiquant occasionnel Aussi important que le reste Equilibre Non Non Oui Oui Oui Oui Oui 0.3
1783 21 Homme NA 4155.16642 Etudiant, eleve NA 5 Oui Pratiquant regulier NA NA Non Non Non Non Oui Oui Oui 2.0
1784 45 Femme 1er cycle 1773.73858 Exerce une profession Employe 8 Oui Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Non Non Non Non 1.0
1785 52 Femme Derniere annee d’etudes primaires 2659.17710 Autre inactif Employe 6 Non NSP ou NVPR NA NA Non Non Oui Oui Non Non Non 6.0
1786 30 Homme Enseignement technique ou professionnel long 7778.91096 Exerce une profession Ouvrier qualifie 2 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Oui Non Non 2.0
1787 28 Femme NA 7919.49784 Exerce une profession Autre 2 Non Rejet Aussi important que le reste Equilibre Non Non Non Non Non Oui Oui 3.0
1788 76 Homme Derniere annee d’etudes primaires 2535.76785 Retraite Cadre 0 Non Pratiquant occasionnel NA NA Non Non Non Non Oui Non Non 1.0
1789 56 Homme 2eme cycle 6861.69279 Autre inactif NA 3 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 4.0
1790 55 Femme 1er cycle 11654.06930 Exerce une profession Employe 1 Oui Pratiquant regulier Aussi important que le reste Satisfaction Non Non Non Oui Non Oui Non 1.0
1791 54 Homme Derniere annee d’etudes primaires 468.17776 Exerce une profession Ouvrier qualifie 1 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Non Oui 2.0
1792 25 Homme Enseignement technique ou professionnel long 7420.78298 Exerce une profession Employe 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Oui Oui 2.0
1793 42 Homme Enseignement superieur y compris technique superieur 2199.70565 Exerce une profession Profession intermediaire 3 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Oui Oui Oui 1.0
1794 51 Femme Enseignement technique ou professionnel court 10933.32354 Exerce une profession Employe 2 Non Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Non Oui Oui Non Non 3.0
1795 20 Femme Enseignement technique ou professionnel court 6352.83859 Chomeur Ouvrier specialise 4 Non Rejet NA NA Non Non Non Oui Oui Oui Oui 3.0
1796 23 Femme Enseignement superieur y compris technique superieur 1772.86054 Chomeur NA 8 Non Pratiquant regulier NA NA Non Non Non Oui Oui Non Non 3.0
1797 52 Homme Derniere annee d’etudes primaires 1204.39140 Exerce une profession Ouvrier specialise 2 Oui Pratiquant occasionnel Peu important Insatisfaction Non Non Non Oui Oui Non Oui 3.0
1798 62 Femme 2eme cycle 8893.42882 Retraite Employe 0 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 0.1
1799 76 Femme Enseignement technique ou professionnel court 445.34756 Retraite Employe 0 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Oui 1.0
1800 60 Homme N’a jamais fait d’etudes 3673.61405 Retire des affaires NA 2 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 3.0
1801 60 Homme Enseignement superieur y compris technique superieur 4552.64658 Exerce une profession NA 0 Non Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Non Oui Non Non Non 3.0
1802 53 Femme N’a jamais fait d’etudes 376.18012 Au foyer NA 4 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 2.0
1803 79 Femme Derniere annee d’etudes primaires 9664.31868 Retire des affaires NA 1 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 3.0
1804 74 Femme 1er cycle 153.01026 Retraite Cadre 3 Non Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 1.0
1805 39 Femme Enseignement superieur y compris technique superieur 2385.04522 Exerce une profession Cadre 0 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Non Oui Oui 0.3
1806 48 Homme Enseignement technique ou professionnel court 685.92819 Exerce une profession Technicien 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Oui Oui Oui Non Non 2.0
1807 50 Homme Enseignement technique ou professionnel court 3010.84595 Chomeur Ouvrier qualifie 7 Non Rejet NA NA Non Non Non Oui Oui Non Non 1.0
1808 47 Homme Enseignement technique ou professionnel court 26204.71333 Exerce une profession NA 2 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 1.0
1809 40 Homme Enseignement technique ou professionnel court 7313.12195 Exerce une profession Ouvrier qualifie 5 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Oui Oui Non 4.0
1810 70 Homme Derniere annee d’etudes primaires 2987.63317 Retraite Employe 9 Oui Pratiquant regulier NA NA Non Non Oui Oui Oui Non Oui 3.0
1811 49 Femme Enseignement technique ou professionnel court 5971.25129 Exerce une profession Profession intermediaire 0 Oui Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Oui Oui Oui Non 2.0
1812 30 Homme Enseignement superieur y compris technique superieur 10221.11523 Exerce une profession Cadre 1 Oui Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Non Non Oui Oui 3.0
1813 32 Femme Enseignement superieur y compris technique superieur 8573.47011 Exerce une profession Cadre 1 Oui Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Non Non Non Oui Non 1.0
1814 60 Homme N’a jamais fait d’etudes 7527.36948 Autre inactif Employe 4 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 0.0
1815 39 Homme 1er cycle 2008.82398 Exerce une profession Ouvrier specialise 3 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Non Non 8.0
1816 58 Homme Enseignement technique ou professionnel court 5765.98393 Chomeur Ouvrier specialise 3 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 6.0
1817 74 Femme Derniere annee d’etudes primaires 12265.60802 Retire des affaires NA 2 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 3.0
1818 43 Homme Enseignement technique ou professionnel court 7869.06200 Exerce une profession Profession intermediaire 7 Non Rejet Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 1.0
1819 31 Femme Enseignement technique ou professionnel court 10015.64186 Exerce une profession Employe 7 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Non 3.0
1820 51 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 4626.01172 Exerce une profession Ouvrier specialise 12 Non Appartenance sans pratique Le plus important Satisfaction Non Non Non Non Non Non Non 1.0
1821 34 Femme 2eme cycle 2105.36184 Exerce une profession Employe 1 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Non 1.0
1822 29 Homme Enseignement technique ou professionnel long 9874.84168 Exerce une profession Ouvrier specialise 2 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Oui Oui 3.0
1823 71 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 8278.10213 Au foyer Employe 2 Oui Pratiquant regulier NA NA Non Non Non Oui Non Non Non 3.0
1824 33 Femme Enseignement superieur y compris technique superieur 6271.81297 Exerce une profession Employe 1 Oui Pratiquant occasionnel Moins important que le reste Insatisfaction Non Non Non Oui Oui Non Oui 0.0
1825 44 Femme 2eme cycle 1533.94309 Exerce une profession Profession intermediaire 2 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Non 5.0
1826 81 Femme Derniere annee d’etudes primaires 13074.78210 Retire des affaires NA 0 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 2.0
1827 57 Homme Enseignement technique ou professionnel long 3846.18425 Exerce une profession Cadre 3 Non Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Non Oui Oui Non Non 2.0
1828 24 Femme Enseignement technique ou professionnel court 7441.14711 Chomeur Employe 2 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Oui Non 3.0
1829 33 Femme N’a jamais fait d’etudes 3019.93207 Au foyer NA 15 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 5.0
1830 54 Femme Derniere annee d’etudes primaires 2045.69969 Exerce une profession Employe 2 Oui Pratiquant regulier Peu important Insatisfaction Non Oui Non Oui Non Non Non 2.0
1831 57 Femme Enseignement superieur y compris technique superieur 5837.60349 Exerce une profession NA 3 Non Pratiquant regulier Aussi important que le reste Satisfaction Non Non Non Non Non Oui Oui 2.0
1832 36 Femme Enseignement technique ou professionnel long 1976.82981 Exerce une profession NA 5 Non Appartenance sans pratique Le plus important Insatisfaction Non Non Oui Oui Non Non Oui 0.6
1833 55 Femme Derniere annee d’etudes primaires 5190.20730 Exerce une profession Employe 2 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Non 4.0
1834 54 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 3071.78227 Exerce une profession Technicien 5 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Oui Non Non Oui Non Oui 4.0
1835 37 Femme 2eme cycle 6165.34358 Exerce une profession Employe 2 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Oui Oui Non 2.0
1836 66 Femme Enseignement superieur y compris technique superieur 5978.98187 Retraite Cadre 2 Oui Rejet NA NA Non Non Oui Oui Oui Non Non 2.0
1837 78 Femme 2eme cycle 5329.88558 Retraite Employe 0 Oui Pratiquant regulier NA NA Non Non Non Oui Non Non Non 6.0
1838 39 Femme Enseignement technique ou professionnel court 23845.70710 Exerce une profession Employe 6 Oui Ni croyance ni appartenance Peu important Satisfaction Non Non Non Oui Oui Oui Oui 0.0
1839 32 Femme Enseignement technique ou professionnel court 1059.87804 Exerce une profession NA 2 Oui Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Non Non Non Oui 1.0
1840 67 Femme Derniere annee d’etudes primaires 1828.98984 Au foyer NA 1 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 3.0
1841 61 Homme Derniere annee d’etudes primaires 5118.13179 Retraite Employe 5 Non Appartenance sans pratique NA NA Non Non Oui Oui Oui Non Non 2.0
1842 48 Femme Enseignement technique ou professionnel court 3912.49163 Exerce une profession Employe 1 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Non Non Non 2.0
1843 44 Femme Enseignement technique ou professionnel court 910.86014 Exerce une profession Employe 6 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Non Oui Non 0.4
1844 83 Femme Derniere annee d’etudes primaires 7854.38037 Retraite Employe 2 Oui Ni croyance ni appartenance NA NA Non Non Non Oui Non Non Non 8.0
1845 76 Femme Derniere annee d’etudes primaires 7483.06141 Au foyer NA 3 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 3.0
1846 46 Homme Enseignement superieur y compris technique superieur 9248.73784 Exerce une profession Autre 0 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Oui Oui Non 2.0
1847 21 Homme Enseignement technique ou professionnel court 4630.43620 Chomeur Ouvrier qualifie 2 Ne sait pas Ni croyance ni appartenance NA NA Oui Non Non Non Non Non Non 2.0
1848 54 Homme Enseignement technique ou professionnel long 851.70090 Exerce une profession Technicien 1 Non Ni croyance ni appartenance Moins important que le reste Insatisfaction Non Non Non Non Oui Non Non 3.0
1849 45 Femme 2eme cycle 1127.43682 Chomeur Employe 5 Oui Appartenance sans pratique NA NA Non Non Non Oui Oui Non Non 2.0
1850 83 Homme 1er cycle 2940.48202 Retraite Profession intermediaire 4 Non Rejet NA NA Non Non Non Non Non Non Oui 6.0
1851 33 Homme 2eme cycle 976.82434 Chomeur Ouvrier qualifie 2 Non Ni croyance ni appartenance NA NA Non Non Non Non Oui Non Non 0.0
1852 60 Femme Enseignement superieur y compris technique superieur 16066.90836 Retraite Profession intermediaire 7 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Oui 1.0
1853 54 Femme Enseignement technique ou professionnel court 913.84435 Exerce une profession Employe 5 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Oui Oui Non Oui Non 3.0
1854 30 Femme Enseignement superieur y compris technique superieur 7205.15184 Exerce une profession Profession intermediaire 3 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Non Oui 0.9
1855 26 Homme Enseignement superieur y compris technique superieur 12544.41826 Exerce une profession NA 1 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 1.0
1856 24 Femme NA 7147.28264 Exerce une profession Cadre 3 Oui Ni croyance ni appartenance Moins important que le reste Satisfaction Non Oui Non Non Non Oui Oui 1.1
1857 65 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 3203.19253 Retraite Ouvrier specialise 7 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 3.0
1858 65 Homme Enseignement technique ou professionnel long 8737.52614 Retraite Technicien 0 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Non Oui 6.0
1859 81 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 1176.20740 Au foyer Ouvrier specialise 9 Oui NSP ou NVPR NA NA Non Non Non Non Non Non Non 5.0
1860 57 Homme Enseignement superieur y compris technique superieur 678.72588 Exerce une profession Technicien 5 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Oui Non 4.0
1861 27 Femme Enseignement superieur y compris technique superieur 13059.79408 Exerce une profession Employe 2 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Non Non Non 2.0
1862 38 Femme Enseignement technique ou professionnel court 10850.09252 Au foyer Employe 2 Oui NSP ou NVPR NA NA Non Non Non Non Non Non Oui 2.0
1863 79 Homme Derniere annee d’etudes primaires 2563.83710 Retraite Ouvrier specialise 9 Oui Pratiquant occasionnel NA NA Non Non Non Non Oui Non Non 6.0
1864 64 Homme Enseignement technique ou professionnel court 1205.42291 Retraite Employe 1 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 3.0
1865 44 Femme Enseignement technique ou professionnel court 5151.49801 Exerce une profession Employe 2 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 2.0
1866 33 Homme Enseignement technique ou professionnel court 2272.36117 Exerce une profession Ouvrier qualifie 2 Non Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Oui Oui Oui Non Oui 3.0
1867 22 Femme Enseignement technique ou professionnel long 3287.62936 Exerce une profession Employe 5 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Non Oui Oui 2.0
1868 80 Homme Derniere annee d’etudes primaires 1197.33916 Retraite Ouvrier qualifie 3 Non Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 0.0
1869 49 Femme 2eme cycle 2558.43563 Au foyer Autre 4 Oui Ni croyance ni appartenance NA NA Non Oui Non Oui Non Oui Non 3.0
1870 40 Femme Enseignement superieur y compris technique superieur 6235.83764 Au foyer Employe 6 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Oui 8.0
1871 29 Homme 1er cycle 7195.25746 Exerce une profession Employe 4 Oui Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Oui Oui Oui Oui Oui 2.0
1872 57 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 6654.55698 Au foyer Ouvrier specialise 9 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 0.0
1873 53 Homme 1er cycle 2640.19177 Exerce une profession Profession intermediaire 2 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Oui Non Oui 1.0
1874 50 Femme 2eme cycle 4011.82960 Exerce une profession Employe 7 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Oui 0.6
1875 53 Femme Enseignement technique ou professionnel long 8439.80977 Exerce une profession Profession intermediaire 2 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Non Oui Oui 1.0
1876 51 Femme Derniere annee d’etudes primaires 19413.73042 Au foyer Ouvrier qualifie 3 Non Appartenance sans pratique NA NA Non Oui Non Oui Non Non Non 3.0
1877 49 Homme Enseignement technique ou professionnel court 8487.99867 Exerce une profession NA 2 Non Pratiquant occasionnel Aussi important que le reste Satisfaction Non Non Oui Oui Non Oui Oui 2.0
1878 22 Homme NA 23299.32407 Etudiant, eleve NA 8 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Oui 0.0
1879 48 Femme Enseignement technique ou professionnel court 7980.06339 Exerce une profession NA 4 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Non Non 2.0
1880 64 Homme Enseignement technique ou professionnel court 8742.18026 Retraite Ouvrier qualifie 8 Oui Rejet NA NA Non Non Non Oui Oui Non Oui 0.0
1881 33 Homme Enseignement technique ou professionnel court 7535.84118 Exerce une profession Employe 3 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Oui Non Non 2.9
1882 49 Homme Enseignement technique ou professionnel court 5079.08146 Exerce une profession Employe 9 Oui Ni croyance ni appartenance Le plus important Equilibre Non Non Oui Non Oui Oui Non 4.0
1883 46 Homme 2eme cycle 5641.48992 Exerce une profession Technicien 1 Non Appartenance sans pratique Peu important Satisfaction Non Oui Non Non Oui Non Non 0.0
1884 42 Femme Enseignement technique ou professionnel court 1648.61108 Au foyer Employe 2 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Oui Oui 0.0
1885 51 Homme 1er cycle 2973.70773 Exerce une profession Technicien 3 Non Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Oui Non Oui Non 1.0
1886 54 Homme Enseignement superieur y compris technique superieur 3707.44354 Exerce une profession Cadre 4 Oui Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Non Non Oui Oui Non 1.0
1887 66 Femme Derniere annee d’etudes primaires 9280.53471 Retraite Employe 1 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Oui Oui 5.0
1888 39 Femme 1er cycle 2917.45700 Au foyer NA 5 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 6.0
1889 43 Femme Enseignement superieur y compris technique superieur 7300.57390 Chomeur Employe 4 Non Appartenance sans pratique NA NA Non Non Non Oui Non Oui Non 2.0
1890 48 Femme Enseignement technique ou professionnel long 2742.54883 Exerce une profession Employe 1 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Oui Non Oui Non Non Non 2.1
1891 34 Femme Enseignement superieur y compris technique superieur 4110.22906 Exerce une profession Employe 1 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Oui Non 2.0
1892 33 Homme Enseignement superieur y compris technique superieur 5401.80511 Exerce une profession Cadre 4 Non Ni croyance ni appartenance Aussi important que le reste Satisfaction Non Non Non Oui Oui Non Oui 2.0
1893 65 Homme Derniere annee d’etudes primaires 1944.67117 Retraite Ouvrier qualifie 6 Oui Ni croyance ni appartenance NA NA Non Non Oui Non Oui Non Oui 0.0
1894 55 Homme Enseignement superieur y compris technique superieur 8592.37070 Exerce une profession NA 2 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Oui Non Non 0.0
1895 42 Homme Enseignement superieur y compris technique superieur 6959.71609 Exerce une profession NA 0 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Oui Oui Oui 1.0
1896 45 Femme 2eme cycle 1754.43878 Exerce une profession Cadre 3 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Oui Non Oui Oui Oui Non 1.0
1897 66 Femme Derniere annee d’etudes primaires 4970.03148 Retraite Employe 0 Oui Pratiquant occasionnel NA NA Non Oui Non Non Oui Non Oui 4.0
1898 48 Homme Enseignement technique ou professionnel court 7032.94148 Exerce une profession Ouvrier qualifie 4 Oui Pratiquant occasionnel Moins important que le reste Insatisfaction Non Non Non Oui Oui Non Non 0.6
1899 67 Femme Derniere annee d’etudes primaires 5362.81209 Autre inactif NA 9 Oui Pratiquant regulier NA NA Non Non Non Oui Non Non Oui 4.0
1900 41 Femme Enseignement technique ou professionnel court 2968.87057 Exerce une profession Employe 4 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Non Non Non Non 2.0
1901 56 Femme 1er cycle 1200.06506 Exerce une profession Employe 2 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Oui Oui Oui Non Non 1.0
1902 48 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 5371.58970 Exerce une profession Employe 8 Non Pratiquant occasionnel Peu important Equilibre Non Non Non Non Non Non Non 3.0
1903 45 Homme Enseignement technique ou professionnel court 6040.78253 Chomeur Ouvrier qualifie 2 Non Rejet NA NA Non Non Non Oui Oui Oui Non NA
1904 63 Homme Derniere annee d’etudes primaires 4930.67600 Retraite Ouvrier specialise 2 Oui Pratiquant occasionnel NA NA Non Non Oui Oui Oui Non Non 5.0
1905 63 Femme Derniere annee d’etudes primaires 1365.43180 Retraite Ouvrier qualifie 2 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 6.0
1906 34 Homme Enseignement superieur y compris technique superieur 2806.93096 Chomeur Cadre 3 Non Ni croyance ni appartenance NA NA Non Non Non Oui Oui Non Non 4.0
1907 50 Femme 2eme cycle 6147.69713 Exerce une profession Ouvrier qualifie 4 Non Pratiquant regulier Moins important que le reste Equilibre Non Non Non Non Non Oui Non 0.0
1908 48 Homme Enseignement superieur y compris technique superieur 6697.86825 Exerce une profession Cadre 2 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Non Oui Non 3.0
1909 47 Homme Enseignement technique ou professionnel court 11414.38776 Exerce une profession Ouvrier qualifie 3 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Oui Non Oui Non Oui 1.0
1910 47 Homme 2eme cycle 7256.11397 Exerce une profession Employe 3 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Non Non Non 1.0
1911 69 Femme 2eme cycle 10880.90929 Retraite Employe 1 Non Pratiquant regulier NA NA Non Non Non Non Non Oui Oui 0.0
1912 50 Femme Enseignement technique ou professionnel court 6715.65990 Exerce une profession Ouvrier specialise 2 Oui Appartenance sans pratique Peu important Insatisfaction Non Non Non Oui Non Oui Non 2.0
1913 43 Femme Enseignement superieur y compris technique superieur 24358.80212 Exerce une profession Employe 2 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Oui Oui Non Non Oui 3.0
1914 80 Femme Enseignement superieur y compris technique superieur 2359.28727 Retraite Cadre 0 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Oui 1.0
1915 53 Femme Enseignement technique ou professionnel court 4184.20745 Exerce une profession Employe 0 Non Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Oui Oui Oui Oui 1.0
1916 97 Femme Derniere annee d’etudes primaires 2162.83465 Autre inactif Autre 5 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 3.0
1917 43 Femme Enseignement superieur y compris technique superieur 7325.35942 Exerce une profession Employe 4 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Oui Oui Oui 2.0
1918 54 Homme 1er cycle 2730.96159 Retraite Ouvrier qualifie 11 Non Appartenance sans pratique NA NA Non Non Oui Non Oui Non Non 3.0
1919 77 Femme Derniere annee d’etudes primaires 3941.18683 Au foyer Profession intermediaire 8 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 2.0
1920 62 Femme Derniere annee d’etudes primaires 5040.29690 Au foyer Employe 1 Non Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 5.0
1921 28 Femme Enseignement technique ou professionnel long 3084.25084 Exerce une profession Employe 0 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Non Oui Oui 4.0
1922 65 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 4826.84806 Retraite Employe 6 Non Pratiquant regulier NA NA Non Non Non Non Non Non Non 5.0
1923 56 Femme Enseignement superieur y compris technique superieur 1828.41602 Au foyer NA 3 Oui Pratiquant regulier NA NA Non Non Non Oui Non Oui Oui 0.2
1924 44 Homme 1er cycle 2221.51091 Exerce une profession Ouvrier qualifie 10 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Non Non Non 2.0
1925 22 Homme Enseignement technique ou professionnel court 8882.49835 Exerce une profession Ouvrier qualifie 1 Non Ni croyance ni appartenance Moins important que le reste Satisfaction Non Non Non Non Non Oui Non 2.0
1926 51 Homme Derniere annee d’etudes primaires 3148.59477 Exerce une profession Ouvrier qualifie 7 Oui Ni croyance ni appartenance Aussi important que le reste Equilibre Non Non Non Oui Oui Non Non 3.0
1927 24 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 1854.81667 Exerce une profession Ouvrier specialise 2 Ne sait pas Appartenance sans pratique Peu important Equilibre Non Non Non Oui Non Oui Non 2.9
1928 40 Femme Enseignement superieur y compris technique superieur 6238.89214 Exerce une profession Cadre 1 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 0.1
1929 61 Homme Enseignement technique ou professionnel court 6294.86715 Retraite Employe 1 Non Ni croyance ni appartenance NA NA Non Non Oui Non Non Non Non 5.0
1930 36 Homme Enseignement technique ou professionnel court 896.34470 Exerce une profession Ouvrier qualifie 4 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Oui Oui Non 5.0
1931 27 Femme 1er cycle 13332.43037 Au foyer Employe 6 Non Appartenance sans pratique NA NA Non Non Non Oui Non Oui Oui 3.0
1932 23 Femme NA 7128.36274 Etudiant, eleve NA 0 Oui Ni croyance ni appartenance NA NA Non Oui Non Non Non Oui Oui 0.4
1933 38 Femme 1er cycle 2008.16022 Exerce une profession Ouvrier specialise 5 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Non Non Non 5.0
1934 68 Homme A arrete ses etudes, avant la derniere annee d’etudes primaires 5285.44855 Retraite Ouvrier specialise 2 Non Pratiquant regulier NA NA Non Non Non Non Oui Non Oui 4.0
1935 54 Femme N’a jamais fait d’etudes 652.51630 Chomeur Employe 7 Non NSP ou NVPR NA NA Non Non Non Oui Non Non Non 4.0
1936 51 Femme 1er cycle 1360.40329 Exerce une profession Employe 3 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Oui Non Non Non 2.0
1937 18 Homme NA 6400.94194 Etudiant, eleve NA 3 Oui Ni croyance ni appartenance NA NA Non Oui Oui Oui Oui Oui Oui 3.0
1938 66 Femme 1er cycle 7499.20873 Retraite Ouvrier specialise 5 Non Pratiquant regulier NA NA Non Non Non Oui Non Non Non 4.0
1939 49 Homme Enseignement superieur y compris technique superieur 1141.00340 Exerce une profession Cadre 3 Oui Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Oui Oui Oui Oui 1.0
1940 56 Homme Derniere annee d’etudes primaires 21997.57674 Autre inactif Ouvrier qualifie 6 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 2.0
1941 55 Homme Enseignement technique ou professionnel court 6733.95353 Exerce une profession Ouvrier qualifie 5 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Oui Non Non Non Non 3.0
1942 83 Femme 1er cycle 11276.54068 Retraite Employe 0 Oui NSP ou NVPR NA NA Non Non Non Non Non Non Non 3.0
1943 31 Homme Enseignement technique ou professionnel court 14830.85831 Exerce une profession Technicien 2 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Oui Non Oui 2.0
1944 70 Femme Derniere annee d’etudes primaires 6415.15113 Retraite Employe 2 Oui Pratiquant regulier NA NA Non Non Non Oui Non Non Non 3.0
1945 59 Homme 1er cycle 4234.09593 Retraite Profession intermediaire 4 Oui Appartenance sans pratique NA NA Non Non Non Non Oui Non Oui 5.0
1946 25 Homme NA 8087.39535 Etudiant, eleve NA 6 Oui Appartenance sans pratique NA NA Non Non Non Non Non Oui Oui 2.0
1947 48 Femme Enseignement superieur y compris technique superieur 5151.49801 Exerce une profession Profession intermediaire 4 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Oui Non Oui 0.0
1948 76 Femme Derniere annee d’etudes primaires 9597.92920 Retire des affaires NA 0 Non Appartenance sans pratique NA NA Non Non Non Non Non Non Non 3.0
1949 28 Femme Enseignement superieur y compris technique superieur 7147.28264 Exerce une profession Profession intermediaire 0 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 2.0
1950 58 Femme 1er cycle 11613.43407 Au foyer Ouvrier specialise 3 Non Pratiquant occasionnel NA NA Non Non Non Oui Non Non Non 2.0
1951 67 Homme Enseignement technique ou professionnel court 6479.80972 Retire des affaires NA 2 Non Rejet NA NA Non Non Non Non Oui Non Oui 5.0
1952 39 Homme Enseignement technique ou professionnel court 1605.37103 Autre inactif Ouvrier qualifie 0 Non Ni croyance ni appartenance NA NA Non Non Non Non Oui Non Non 0.0
1953 29 Femme 1er cycle 3272.68076 Exerce une profession Employe 2 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Non Non 6.0
1954 67 Femme Enseignement superieur y compris technique superieur 1465.60753 Retraite Cadre 10 Oui Pratiquant regulier NA NA Non Non Non Oui Non Oui Oui 0.0
1955 47 Homme Enseignement technique ou professionnel court 7418.57533 Exerce une profession Employe 5 Oui Rejet Aussi important que le reste Satisfaction Non Non Non Non Oui Oui Oui 0.4
1956 71 Femme Enseignement technique ou professionnel court 6868.35044 Autre inactif Cadre 0 Oui Rejet NA NA Non Non Non Non Non Non Oui 3.0
1957 30 Homme Enseignement technique ou professionnel court 924.66586 Exerce une profession Ouvrier qualifie 6 Non Rejet Moins important que le reste Satisfaction Non Non Oui Non Oui Oui Non 3.0
1958 44 Homme Enseignement technique ou professionnel court 3706.07446 Exerce une profession Ouvrier qualifie 7 Non Ni croyance ni appartenance Moins important que le reste Insatisfaction Non Non Non Non Oui Non Non 2.0
1959 23 Homme Enseignement superieur y compris technique superieur 3495.39270 Exerce une profession Employe 4 Oui Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Oui Oui Oui Oui 2.0
1960 55 Femme 1er cycle 5426.10430 Exerce une profession NA 0 Non Appartenance sans pratique Moins important que le reste Equilibre Non Oui Non Non Non Non Non 0.0
1961 65 Femme Derniere annee d’etudes primaires 5210.14457 Retraite Ouvrier specialise 5 Oui Appartenance sans pratique NA NA Non Non Non Non Non Non Non 3.0
1962 43 Homme 1er cycle 1541.15678 Autre inactif Ouvrier specialise 4 Non Appartenance sans pratique NA NA Non Non Non Non Non Oui Non 7.0
1963 43 Femme Enseignement technique ou professionnel long 1600.95363 Exerce une profession Employe 3 Non Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Non Oui Oui Non 2.0
1964 39 Homme Enseignement superieur y compris technique superieur 1790.77204 Exerce une profession Cadre 0 Non Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Non Oui Non Oui 3.0
1965 54 Femme Enseignement superieur y compris technique superieur 7034.92060 Exerce une profession Employe 3 Oui Appartenance sans pratique Aussi important que le reste Equilibre Non Non Non Non Oui Non Non 0.0
1966 68 Femme A arrete ses etudes, avant la derniere annee d’etudes primaires 1296.18852 Retraite Ouvrier specialise 3 Oui Appartenance sans pratique NA NA Non Non Non Oui Non Non Non 0.4
1967 56 Homme Derniere annee d’etudes primaires 1369.96183 Exerce une profession Ouvrier qualifie 10 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Oui Non Oui Oui Non 3.0
1968 56 Homme 2eme cycle 2519.59962 Exerce une profession Profession intermediaire 1 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Oui Non Oui 1.7
1969 22 Homme Enseignement superieur y compris technique superieur 9292.97620 Exerce une profession Technicien 1 Non Rejet Moins important que le reste Satisfaction Non Non Non Non Oui Oui Oui 3.0
1970 65 Homme Enseignement superieur y compris technique superieur 5802.14765 Retraite Cadre 1 Non Appartenance sans pratique NA NA Non Non Non Non Oui Non Non 2.0
1971 20 Femme NA 1460.36294 Etudiant, eleve NA 2 Oui Rejet NA NA Non Non Non Oui Non Oui Non 0.1
1972 41 Femme Enseignement technique ou professionnel court 7196.23139 Retraite Employe 0 Non Pratiquant regulier NA NA Non Non Non Non Non Non Oui 0.0
1973 33 Femme Enseignement superieur y compris technique superieur 7795.35546 Exerce une profession Employe 2 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Non Non Oui Oui Non Non 0.4
1974 69 Homme Enseignement superieur y compris technique superieur 2375.92748 Retire des affaires NA 1 Oui Pratiquant regulier NA NA Non Non Non Non Non Non Non 1.0
1975 52 Femme Derniere annee d’etudes primaires 729.94988 Exerce une profession Employe 7 Non Rejet Peu important Equilibre Non Non Non Non Non Non Non 3.0
1976 62 Femme Derniere annee d’etudes primaires 1252.49916 Retraite Ouvrier specialise 6 Oui Pratiquant occasionnel NA NA Non Non Non Non Non Non Non 5.0
1977 68 Homme Enseignement technique ou professionnel court 9938.70397 Retraite Cadre 6 Oui Pratiquant occasionnel NA NA Non Non Non Non Oui Non Oui 4.0
1978 61 Femme 2eme cycle 2174.38739 Exerce une profession Cadre 2 Oui Appartenance sans pratique Moins important que le reste Satisfaction Non Non Non Oui Non Oui Oui 1.0
1979 53 Femme Derniere annee d’etudes primaires 567.76117 Exerce une profession Ouvrier specialise 3 Non Pratiquant occasionnel Peu important Insatisfaction Non Non Non Oui Non Non Non 3.0
1980 57 Homme Enseignement technique ou professionnel long 6107.21084 Exerce une profession NA 1 Oui Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Oui Oui Non Non 0.7
1981 26 Femme Enseignement superieur y compris technique superieur 3734.32949 Exerce une profession Profession intermediaire 1 Non Pratiquant regulier Moins important que le reste Satisfaction Non Non Non Non Oui Oui Oui 3.0
1982 52 Homme Enseignement technique ou professionnel court 1269.63861 Exerce une profession Profession intermediaire 4 Oui Appartenance sans pratique Aussi important que le reste Satisfaction Non Non Non Oui Oui Oui Non 1.0
1983 19 Femme NA 7396.80716 Exerce une profession Employe 1 Non Appartenance sans pratique Moins important que le reste Insatisfaction Non Non Non Oui Non Oui Oui 3.0
1984 74 Homme Enseignement superieur y compris technique superieur 4010.07505 Retraite Cadre 1 Non Pratiquant occasionnel NA NA Non Non Non Non Non Oui Non 0.0
1985 40 Femme 2eme cycle 2073.65504 Exerce une profession Ouvrier qualifie 8 Non Appartenance sans pratique Peu important Insatisfaction Non Non Non Oui Oui Oui Oui 0.0
1986 38 Homme Enseignement superieur y compris technique superieur 6118.81300 Exerce une profession Cadre 4 Oui Pratiquant occasionnel Moins important que le reste Satisfaction Non Oui Non Oui Oui Oui Oui 2.0
1987 27 Homme Enseignement superieur y compris technique superieur 14848.41298 Exerce une profession Profession intermediaire 0 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Oui Oui Oui Non Oui 2.0
1988 31 Homme Enseignement technique ou professionnel long 1862.61377 Chomeur Technicien 3 Non Ni croyance ni appartenance NA NA Non Non Non Non Non Oui Oui 2.0
1989 49 Homme Enseignement technique ou professionnel court 9721.73309 Exerce une profession Ouvrier qualifie 4 Oui Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Non Non Non 2.0
1990 49 Femme 2eme cycle 3944.08480 Exerce une profession Employe 11 Oui NSP ou NVPR Moins important que le reste Satisfaction Non Non Non Oui Oui Oui Oui 1.0
1991 52 Femme Derniere annee d’etudes primaires 2801.38168 Exerce une profession Employe 10 Oui Pratiquant regulier Moins important que le reste Equilibre Non Non Non Oui Oui Oui Non 1.4
1992 42 Femme Enseignement technique ou professionnel long 2039.15205 Chomeur Ouvrier qualifie 2 Oui Pratiquant occasionnel NA NA Non Non Non Oui Non Non Oui 0.0
1993 50 Homme Enseignement superieur y compris technique superieur 12381.58975 Exerce une profession NA 3 Non Pratiquant occasionnel Moins important que le reste Equilibre Non Non Non Non Oui Non Oui NA
1994 41 Homme Enseignement superieur y compris technique superieur 1113.84193 Exerce une profession Profession intermediaire 7 Non Pratiquant occasionnel Moins important que le reste Satisfaction Non Oui Non Oui Oui Oui Oui 0.1
1995 46 Femme Enseignement technique ou professionnel court 8408.24514 Au foyer Autre 0 Non Appartenance sans pratique NA NA Non Non Non Oui Non Non Oui 2.0
1996 45 Homme Enseignement technique ou professionnel court 8092.14727 Exerce une profession Technicien 3 Non Ni croyance ni appartenance Moins important que le reste Equilibre Non Non Non Non Oui Non Non 3.0
1997 46 Homme Enseignement technique ou professionnel court 955.87873 Exerce une profession Ouvrier qualifie 4 Oui Pratiquant occasionnel Le plus important Equilibre Non Non Oui Oui Oui Non Non 0.0
1998 24 Homme Enseignement technique ou professionnel long 5320.16239 Exerce une profession Technicien 1 Oui Rejet Moins important que le reste Satisfaction Non Non Non Non Oui Oui Oui 1.4
1999 24 Femme Enseignement technique ou professionnel court 13740.80950 Exerce une profession Employe 2 Non Appartenance sans pratique Moins important que le reste Equilibre Non Non Non Non Non Oui Non 0.3
2000 66 Femme Enseignement technique ou professionnel long 7709.51312 Au foyer Employe 3 Non Appartenance sans pratique NA NA Non Oui Non Oui Non Non Non 0.0

Une autre alternative est d’utiliser kable, ou encore la fonction datatable de l’extension DT, qui propose encore davantage d’interactivité :

DT::datatable(hdv2003)

Dans tous les cas il est déconseillé d’afficher de cette manière un tableau de données de très grandes dimensions, car le fichier HTML résultant contiendrait l’ensemble des données et serait donc très volumineux.

On peut définir un mode d’affichage par défaut pour tous les tableaux de données en modifiant les Output options du format HTML (onglet General, Print dataframes as), ou en modifiant manuellement l’option df_print de l’entrée html_document dans le préambule.

À noter que les tableaux issus de la fonction freq de questionr s’affichent comme des tableaux de données (et non comme des tableaux croisés).

Autres extensions pour présenter des tableaux

Il existe de nombreuses extensions offrant des fonctionnalités de présentation enrichie des tableaux et autres objets R.

printr

L’extension printr développée par le même auteur que knitr étent le fonctionnement par défaut de knitr. Une fois chargée, le rendu automatique de certains objets (tel qu’un tableau croisé à trois variables) sera amélioré.

library(printr)
x1 <- sample(letters[1:2], 1000, TRUE)
x2 <- sample(letters[1:2], 1000, TRUE)
x3 <- sample(letters[1:2], 1000, TRUE)
table(x1, x2, x3)
x1 x2 x3 Freq
a a a 131
b 110
b a 115
b 134
b a a 151
b 120
b a 118
b 121

Pour d’autres exemples, voir la documentation de l’extension sur https://yihui.name/printr/.

kableExtra

L’extension kableExtra a pour objectif d’étendre la fonction kable de knitr avec des options comme la possibilité de regrouper des colonnes, ajouter des notes de tableau, coloriser certaines cellules…

library(kableExtra)
dt <- mtcars[1:5, 1:4]

kable(dt, format = "html", caption = "Demo Table") %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = F
  ) %>%
  add_header_above(c(" ", "Group 1" = 2, "Group 2[note]" = 2)) %>%
  add_footnote(c("table footnote"))
Demo Table
Group 1
Group 2a
mpg cyl disp hp
Mazda RX4 21.0 6 160 110
Mazda RX4 Wag 21.0 6 160 110
Datsun 710 22.8 4 108 93
Hornet 4 Drive 21.4 6 258 110
Hornet Sportabout 18.7 8 360 175
a table footnote

Pour une présentation détaillée, vous pouvez vous référer aux vignettes disponibles avec l’extension.

Notamment, il est possible d’utiliser kableExtra en conjonction avec l’extension formattable pour des rendus colorés et encore plus personnalisé de vos tableaux (voir la vignette dédiée).

library(knitr)
library(kableExtra)
library(formattable)
library(dplyr, quietly = TRUE)
mtcars[1:5, 1:4] %>%
  mutate(
    car = row.names(.),
    mpg = color_tile("white", "orange")(mpg),
    cyl = cell_spec(cyl, "html",
      angle = (1:5) * 60,
      background = "red", color = "white", align = "center"
    ),
    disp = ifelse(disp > 200,
      cell_spec(disp, "html", color = "red", bold = T),
      cell_spec(disp, "html", color = "green", italic = T)
    ),
    hp = color_bar("lightgreen")(hp)
  ) %>%
  select(car, everything()) %>%
  kable("html", escape = F) %>%
  kable_styling("hover", full_width = F) %>%
  column_spec(5, width = "3cm") %>%
  add_header_above(c(" ", "Hello" = 2, "World" = 2))
Hello
World
car mpg cyl disp hp
Mazda RX4 21.0 6 160 110
Mazda RX4 Wag 21.0 6 160 110
Datsun 710 22.8 4 108 93
Hornet 4 Drive 21.4 6 258 110
Hornet Sportabout 18.7 8 360 175

gt

L’extension gt en cours de développement par l’équipe de RStudio vise, un peu sur le modèle de ggplot2, à proposer une grammaire des tableaux. L’extension n’est pour le moment compatible qu’avec un rendu HTML mais la prise en compte du format PDF est prévue. C’est une extension encore assez nouvelle mais qui risque de se développer assez rapidement vu les équipes en charge de son développement.

library(gt)
exibble %>%
  gt(
    rowname_col = "row",
    groupname_col = "group"
  ) %>%
  tab_spanner(
    label = "Date et/ou Heure",
    columns = vars(date, time, datetime)
  ) %>%
  fmt_number(
    columns = vars(num),
    decimals = 2,
    locale = "fr"
  ) %>%
  fmt_date(
    columns = vars(date),
    date_style = 7
  ) %>%
  fmt_time(
    columns = vars(time),
    time_style = 4
  ) %>%
  fmt_datetime(
    columns = vars(datetime),
    date_style = 6,
    time_style = 4
  ) %>%
  fmt_currency(
    columns = vars(currency),
    currency = "EUR",
    locale = "fr"
  ) %>%
  tab_options(
    column_labels.font.size = "small",
    table.font.size = "small",
    row_group.font.size = "small",
    data_row.padding = px(3)
  ) %>%
  summary_rows(
    groups = TRUE,
    columns = vars(num),
    fns = list(
      moyenne = ~ mean(., na.rm = TRUE),
      total = ~ sum(., na.rm = TRUE)
    )
  ) %>%
  grand_summary_rows(
    columns = vars(currency),
    fns = list("grand total" = ~ sum(., na.rm = TRUE)),
    formatter = fmt_currency,
    currency = "EUR"
  )
num char fctr Date et/ou Heure currency
date time datetime
grp_a
row_1 0,11 apricot one 15 janv. 2015 1:35 janv. 1, 2018 2:22 €49,95
row_2 2,22 banana two 15 févr. 2015 2:40 févr. 2, 2018 2:33 €17,95
row_3 33,33 coconut three 15 mars 2015 3:45 mars 3, 2018 3:44 €1,39
row_4 444,40 durian four 15 avr. 2015 4:50 avr. 4, 2018 3:55 €65 100,00
moyenne 120.02
total 480.06
grp_b
row_5 5 550,00 NA five 15 mai 2015 5:55 mai 5, 2018 4:00 €1 325,81
row_6 NA fig six 15 juin 2015 NA juin 6, 2018 4:11 €13,26
row_7 777 000,00 grapefruit seven NA 7:10 juil. 7, 2018 5:22 NA
row_8 8 880 000,00 honeydew eight 15 août 2015 8:20 NA €0,44
moyenne 3,220,850.00
total 9,662,550.00
grand total €66,508.79

Pour en savoir plus : https://gt.rstudio.com/

Autres extensions

On peut également citer les extensions suivantes :

Pour chacune, vous trouverez une documentation sur leur page CRAN, notamment sous forme de vignettes.

Modèles de documents

On a vu ici la production de documents classiques, mais R Markdown permet de créer bien d’autres choses.

Le site de documentation de l’extension propose une galerie des différentes sorties possibles. On peut ainsi créer des slides, des sites Web ou même des livres entiers, comme le présent document.

Slides

Un usage intéressant est la création de diaporamas pour des présentations sous forme de slides. Le principe reste toujours le même : on mélange texte au format Markdown et code R, et R Markdown transforme le tout en présentations au format HTML ou PDF. En général les différents slides sont séparés au niveau de certains niveaux de titre.

Certains modèles de slides sont inclus avec R Markdown, notamment :

  • ioslides et Slidy pour des présentations HTML
  • beamer pour des présentations en PDF via LaTeX

Quand vous créez un nouveau document dans RStudio, ces modèles sont accessibles via l’entrée Presentation :

Créer une présentation R Markdown
Créer une présentation R Markdown

D’autres extensions, qui doivent être installées séparément, permettent aussi des diaporamas dans des formats variés. On citera notamment :

Une fois l’extension installée, elle propose en général un template de départ lorsqu’on crée un nouveau document dans RStudio. Ceux-ci sont accessibles depuis l’entrée From Template.

Créer une présentation à partir d’un template
Créer une présentation à partir d’un template

Templates

Il existe également différents templates permettant de changer le format et la présentation des documents générés. Une liste de ces formats et leur documentation associée est accessible depuis la page formats de la documentation.

On notera notamment :

  • le template distill comportant de nombreuses options pour des documents scientifiques et techniques au format HTML (plus d’infos sur https://rstudio.github.io/distill/) ;
  • des formats d’article correspondant à des publications dans différentes revues : jss_article, elsevier_article, etc. ;
  • le format Tufte Handouts qui permet de produire des documents PDF ou HTML dans un format proche de celui utilisé par Edward Tufte pour certaines de ses publications.

Enfin, l’extension rmdformats (https://github.com/juba/rmdformats) de Julien Barnier propose plusieurs modèles HTML adaptés notamment pour des documents longs :

Modèle readthedown
Modèle readthedown
Modèle html_clean
Modèle html_clean
Modèle material
Modèle material

Là encore, la plupart du temps, ces modèles de documents proposent un template de départ lorsqu’on crée un nouveau document dans RStudio (entrée From Template) :

Créer un document à partir d’un template
Créer un document à partir d’un template

Ressources

Les ressources suivantes sont toutes en anglais…

Yihui Xie, J. J. Allaire et Garrett Grolemund ont écrit un livre dédié intitulé R Markdown: The Definitive Guide. Ce livre est intégralement accessible à https://bookdown.org/yihui/rmarkdown/.

L’ouvrage R for data science, accessible en ligne, contient un chapitre dédié à R Markdown.

Le site officiel de l’extension contient une documentation très complète, tant pour les débutants que pour un usage avancé.

Enfin, l’aide de RStudio (menu Help puis Cheatsheets) permet d’accéder à deux documents de synthèse : une “antisèche” synthétique (R Markdown Cheat Sheet) et un “guide de référence” plus complet (R Markdown Reference Guide).


  1. On peut citer les formats odt, rtf, Markdown, etc.

  2. Si vous n’utilisez pas ce dernier, l’extension peut être installée à part avec install.packages("rmarkdown") et chargée explicitement avec library(rmarkdown).

  3. Il est possible d’inclure dans un document R Markdown des blocs de code d’autres langages

  4. Ce comportement peut être modifié en cliquant sur l’icône d’engrenage de la barre d’outils et en choisissant Chunk Output in Console

Mettre en forme des nombres

Ce chapitre est en cours d’écriture.

Le plus simple est d’avoir recours à l’extension scales et aux fonctions number, comma, percent, unit, ordinal et pvalue.

Couleurs et Palettes

Noms de couleur

Lorsque l’on doit indiquer à R une couleur, notamment dans les fonctions graphiques, on peut mentionner certaines couleurs en toutes lettres (en anglais) comme "red" ou "blue". La liste des couleurs reconnues par R est disponible sur http://www.stat.columbia.edu/~tzheng/files/Rcolor.pdf.

Couleurs RVB

En informatique, les couleurs sont usuellement codées en Rouge/Vert/Bleu (voir https://fr.wikipedia.org/wiki/Rouge_vert_bleu) et représentées par un code hexadécimal à 6 caractères, précédés du symbole #. Ce code est reconnu par R et on pourra par exemple indiquer "#FF0000" pour la couleur rouge. Le code hexadécimal des différentes couleurs peut s’obtenir aisément sur internet, de nombreux sites étant consacrés aux palettes de couleurs.

Parfois, au lieu du code hexadécimal, les couleurs RVB sont indiquées avec trois chiffres entiers compris entre 0 et 255. La conversion en hexadécimal se fait avec la fonction rgb.

rgb(255, 0, 0, maxColorValue = 255)
[1] "#FF0000"

Palettes de couleurs

Palettes natives

R fournit nativement quelques palettes de couleurs continues telles que rainbow, heat.colors, terrain.colors, topo.colors ou encore cm.colors.

Voici un aperçu de ces palettes de couleurs :

Color Brewer

Le projet Color Brewer a développé des palettes cartographiques, à la fois séquentielles, divergentes et catégorielles, présentées en détail sur http://colorbrewer2.org/. Pour chaque type de palette, et en fonction du nombre de classes, est indiqué sur ce site si la palette est adaptée aux personnes souffrant de daltonisme, si elle est rendra correctement sur écran, en cas d’impression couleur et en cas d’impression en noir et blanc.

Voici un aperçu des différentes palettes disponibles :

L’extension RColorBrewer permets d’accéder à ces palettes sous R.

Si on utilise ggplot2, les palettes Color Brewer sont directement disponibles via les fonctions scale_fill_brewer et scale_colour_brewer.

ATTENTION : les palettes Color Brewer sont seulement implémentées pour des variables catégorielles. Il est cependant possible de les utiliser avec des variables continues en les combinants avec scale_fill_gradientn ou scale_coulour_gradientn (en remplaçant "Set1" par le nom de la palette désirée) :

scale_fill_gradientn(values = RColorBrewer::brewer.pal(6, "Set1"))

Viridis

Les palettes de couleurs de la famille Viridis ont initialement été créées pour Matplolib de telles manières que :

  • les couleurs sont perçues de manière uniformes, même lorsqu’elles sont imprimées en noir et blanc ;
  • les couleurs sont distinguées par les formes les plus courantes de daltonisme.

Voici un aperçu des différentes palettes de cette famille :

Ces palettes sont accessibles de manière générale via l’extension viridis.

Elles sont également implémentées dans gpplot2 via les fonctions scale_fill_viridis_c et scale_colour_viridis_c pour des variables continues et scale_fill_viridis_d et scale_colour_viridis_d pour des variables discrètes.

ggsci

L’extension ggsci fournie plusieurs palettes de couleurs inspirées de journaux scientifiques (comme le Lancet ou le New England Journal of Medicine) mais aussi de séries/films (comme les Simpsons ou Star Trek).

On y trouve également des palettes continues basées sur Material Design de Google.

Toutes ces palettes sont directement utilisables avec ggplot2.

Plus d’informations sur https://cran.r-project.org/web/packages/ggsci/vignettes/ggsci.html.

hrbrthemes

L’extension hrbrthemes propose deux palettes discrètes : ipsum_pal et ft_pal ainsi que les fonctions correspondantes pour ggplot2.

library(hrbrthemes)
scales::show_col(ipsum_pal()(9))

scales::show_col(ft_pal()(9))

ggthemes

L’extension ggthemes fournit plusieurs palettes de couleurs, en particulier few_pal issue de l’ouvrage Show Me the Numbers (2012) de Stephen Few ; colorblind_pal adaptées aux personnes daltoniennes ; ptol_pal inspirée de l’ouvrage Colour Schemes (2012) de Paul Tol ; et diverses autres (voir https://jrnold.github.io/ggthemes/).

library(ggthemes)
scales::show_col(few_pal()(8))

scales::show_col(few_pal("Dark")(8))

scales::show_col(colorblind_pal()(8))

scales::show_col(ptol_pal()(12))

khroma

L’extension khroma implémente elle aussi les palettes de couleurs proposées par Paul Tol dans Colour Schemes (2012) mais de manière plus complète que ggthemes.

library(khroma)
plot_scheme(colour("bright")(7), colours = TRUE)

library(ggplot2)
p <- ggplot(mpg) +
  aes(x = displ, y = hwy, colour = class) +
  geom_point()
p + scale_colour_bright()

plot_scheme(colour("vibrant")(7), colours = TRUE)

p + scale_colour_vibrant()

plot_scheme(colour("muted")(9), colours = TRUE)

p + scale_colour_muted()

Pour plus de détails, voir https://khroma.archaeo.science/articles/tol.html

paletteer

L’extension paletteer vise à proposer une interface unifiée pour l’utilisation de palettes de couleurs fournies par d’autres extensions.

scale_color_paletteer_d et scale_color_paletteer_c permettent de sélectionner une des palettes disponibles avec un usage avec ggplot2. Il existe bien entendu leur équivalent pour l’esthétique fill.

library(paletteer)
ggplot(iris) +
  aes(Sepal.Length, Sepal.Width, color = Species) +
  geom_point() +
  scale_color_paletteer_d("nord::aurora")

Voici une liste de palettes disponibles via paletteer :

Package and Palette Name Color Count and Palette
awtools
a_palette 8
bpalette 16
gpalette 4
mpalette 9
spalette 6
dichromat
BrowntoBlue.10 10
BrowntoBlue.12 12
BluetoDarkOrange.12 12
BluetoDarkOrange.18 18
DarkRedtoBlue.12 12
DarkRedtoBlue.18 18
BluetoGreen.14 14
BluetoGray.8 8
BluetoOrangeRed.14 14
BluetoOrange.10 10
BluetoOrange.12 12
BluetoOrange.8 8
LightBluetoDarkBlue.10 10
LightBluetoDarkBlue.7 7
Categorical.12 12
GreentoMagenta.16 16
SteppedSequential.5 25
dutchmasters
milkmaid 13
pearl_earring 11
view_of_Delft 12
little_street 11
anatomy 7
staalmeesters 7
ggsci
nrc_npg 10
default_aaas 10
default_nejm 8
lanonc_lancet 9
default_jama 7
default_jco 10
default_ucscgb 26
category10_d3 10
category20_d3 20
category20b_d3 20
category20c_d3 20
default_igv 51
alternating_igv 2
default_locuszoom 7
default_uchicago 9
light_uchicago 9
dark_uchicago 9
hallmarks_dark_cosmic 10
hallmarks_light_cosmic 10
signature_substitutions_cosmic 6
springfield_simpsons 16
planetexpress_futurama 12
schwifty_rickandmorty 12
uniform_startrek 7
legacy_tron 7
default_gsea 12
red_material 10
pink_material 10
purple_material 10
deep-purple_material 10
indigo_material 10
blue_material 10
light-blue_material 10
cyan_material 10
teal_material 10
green_material 10
light-green_material 10
lime_material 10
yellow_material 10
amber_material 10
orange_material 10
deep-orange_material 10
brown_material 10
grey_material 10
blue-grey_material 10
ggpomological
pomological_base 7
pomological_palette 9
ggthemes
calc 12
manyeys 19
gdoc 10
fivethirtyeight 6
colorblind 8
Tableau 10 10
Tableau 20 20
Color Blind 10
Seattle Grays 5
Traffic 9
Miller Stone 11
Superfishel Stone 10
Nuriel Stone 9
Jewel Bright 9
Summer 8
Winter 10
Green-Orange-Teal 12
Red-Blue-Brown 12
Purple-Pink-Gray 12
Hue Circle 19
Classic 10 10
Classic 10 Medium 10
Classic 10 Light 10
Classic 20 20
Classic Gray 5 5
Classic Color Blind 10
Classic Traffic Light 9
Classic Purple-Gray 6 6
Classic Purple-Gray 12 12
Classic Green-Orange 6 6
Classic Green-Orange 12 12
Classic Blue-Red 6 6
Classic Blue-Red 12 12
Classic Cyclic 13
few_Light 9
few_Medium 9
few_Dark 9
excel_Atlas 6
excel_Badge 6
excel_Berlin 6
excel_Celestial 6
excel_Crop 6
excel_Depth 6
excel_Droplet 6
excel_Facet 6
excel_Feathered 6
excel_Gallery 6
excel_Headlines 6
excel_Integral 6
excel_Ion_Boardroom 6
excel_Ion 6
excel_Madison 6
excel_Main_Event 6
excel_Mesh 6
excel_Office_Theme 6
excel_Organic 6
excel_Parallax 6
excel_Parcel 6
excel_Retrospect 6
excel_Savon 6
excel_Slice 6
excel_Vapor_Trail 6
excel_View 6
excel_Wisp 6
excel_Wood_Type 6
excel_Aspect 6
excel_Blue_Green 6
excel_Blue_II 6
excel_Blue_Warm 6
excel_Blue 6
excel_Grayscale 6
excel_Green_Yellow 6
excel_Green 6
excel_Marquee 6
excel_Median 6
excel_Office_2007-2010 6
excel_Orange_Red 6
excel_Orange 6
excel_Paper 6
excel_Red_Orange 6
excel_Red_Violet 6
excel_Red 6
excel_Slipstream 6
excel_Violet_II 6
excel_Violet 6
excel_Yellow_Orange 6
excel_Yellow 6
wsj_rgby 4
wsj_red_green 2
wsj_black_green 4
wsj_dem_rep 3
wsj_colors6 6
stata_s2color 15
stata_s1rcolor 15
stata_s1color 15
stata_mono 15
stata_economist 15
hc_default 10
hc_darkunica 11
hc_bg 5
hc_fg 12
ghibli
MarnieLight1 7
MarnieMedium1 7
MarnieDark1 7
MarnieLight2 7
MarnieMedium2 7
MarnieDark2 7
PonyoLight 7
PonyoMedium 7
PonyoDark 7
LaputaLight 7
LaputaMedium 7
LaputaDark 7
MononokeLight 7
MononokeMedium 7
MononokeDark 7
SpiritedLight 7
SpiritedMedium 7
SpiritedDark 7
YesterdayLight 7
YesterdayMedium 7
YesterdayDark 7
KikiLight 7
KikiMedium 7
KikiDark 7
TotoroLight 7
TotoroMedium 7
TotoroDark 7
grDevices
blues9 9
jcolors
default 5
pal2 5
pal3 5
pal4 6
pal5 6
pal6 8
pal7 8
pal8 12
pal9 6
pal10 10
pal11 12
pal12 13
rainbow 9
LaCroixColoR
PassionFruit 6
Mango 6
Pure 6
Lime 6
Lemon 6
Orange 6
Berry 6
CranRaspberry 6
Pamplemousse 6
PeachPear 6
Coconut 6
Apricot 6
Tangerine 7
KeyLime 5
PommeBaya 5
CeriseLimon 6
PinaFraise 6
KiwiSandia 7
MelonPomelo 6
MurePepino 6
paired 14
NineteenEightyR
cobra 6
electronic_night 5
hotpink 5
malibu 5
miami1 5
miami2 5
seventies_aint_done_yet 5
sonny 5
sunset1 5
sunset2 5
sunset3 5
youngturqs 12
nord
polarnight 4
snowstorm 3
frost 4
aurora 5
lumina 5
mountain_forms 5
silver_mine 5
lake_superior 6
victory_bonds 5
halifax_harbor 6
moose_pond 8
algoma_forest 7
rocky_mountain 6
red_mountain 8
baie_mouton 7
afternoon_prarie 9
ochRe
namatjira_qual 8
namatjira_div 8
mccrea 11
parliament 8
tasmania 7
nolan_ned 5
winmar 7
olsen_qual 6
olsen_seq 14
williams_pilbara 7
healthy_reef 9
emu_woman_paired 18
galah 6
lorikeet 6
dead_reef 6
jumping_frog 5
palettetown
bulbasaur 13
ivysaur 13
venusaur 14
charmander 13
charmeleon 12
charizard 14
squirtle 14
wartortle 13
blastoise 14
caterpie 12
metapod 5
butterfree 13
weedle 11
kakuna 8
beedrill 14
pidgey 12
pidgeotto 13
pidgeot 14
rattata 13
raticate 13
spearow 15
fearow 12
ekans 12
arbok 10
pikachu 10
raichu 14
sandshrew 10
sandslash 13
nidoranf 11
nidorina 13
nidoqueen 13
nidoranm 10
nidorino 12
nidoking 11
clefairy 13
clefable 12
vulpix 13
ninetales 7
jigglypuff 11
wigglytuff 12
zubat 11
golbat 11
oddish 10
gloom 14
vileplume 13
paras 12
parasect 11
venonat 14
venomoth 11
diglett 4
dugtrio 12
meowth 13
persian 12
psyduck 10
golduck 13
mankey 14
primeape 15
growlithe 11
arcanine 14
poliwag 11
poliwhirl 9
poliwrath 9
abra 8
kadabra 14
alakazam 12
machop 13
machoke 13
machamp 13
bellsprout 13
weepinbell 14
victreebel 14
tentacool 14
tentacruel 14
geodude 6
graveler 6
golem 12
ponyta 11
rapidash 11
slowpoke 12
slowbro 13
magnemite 14
magneton 14
farfetch'd 14
doduo 9
dodrio 15
seel 11
dewgong 7
grimer 9
muk 8
shellder 9
cloyster 9
gastly 8
haunter 10
gengar 10
onix 6
drowzee 9
hypno 9
krabby 10
kingler 10
voltorb 9
electrode 10
exeggcute 9
exeggutor 14
cubone 13
marowak 14
hitmonlee 12
hitmonchan 13
lickitung 9
koffing 12
weezing 13
rhyhorn 8
rhydon 11
chansey 9
tangela 9
kangaskhan 14
horsea 10
seadra 10
goldeen 11
seaking 12
staryu 12
starmie 12
mr. mime 12
scyther 12
jynx 15
electabuzz 10
magmar 12
pinsir 9
tauros 13
magikarp 13
gyarados 15
lapras 15
ditto 6
eevee 9
vaporeon 15
jolteon 11
flareon 10
porygon 11
omanyte 12
omastar 12
kabuto 11
kabutops 9
aerodactyl 7
snorlax 14
articuno 12
zapdos 10
moltres 14
dratini 9
dragonair 12
dragonite 13
mewtwo 9
mew 6
chikorita 11
bayleef 14
meganium 14
cyndaquil 13
quilava 14
typhlosion 14
totodile 11
croconaw 13
feraligatr 14
sentret 12
furret 11
hoothoot 13
noctowl 13
ledyba 12
ledian 14
spinarak 14
ariados 14
crobat 9
chinchou 13
lanturn 14
pichu 11
cleffa 11
igglybuff 9
togepi 12
togetic 11
natu 14
xatu 15
mareep 14
flaaffy 13
ampharos 12
bellossom 13
marill 10
azumarill 10
sudowoodo 11
politoed 14
hoppip 10
skiploom 11
jumpluff 13
aipom 12
sunkern 13
sunflora 12
yanma 11
wooper 9
quagsire 9
espeon 9
umbreon 10
murkrow 12
slowking 13
misdreavus 13
unown 5
wobbuffet 8
girafarig 13
pineco 5
forretress 10
dunsparce 13
gligar 12
steelix 7
snubbull 12
granbull 11
qwilfish 12
scizor 11
shuckle 12
heracross 11
sneasel 14
teddiursa 12
ursaring 13
slugma 9
magcargo 12
swinub 9
piloswine 12
corsola 9
remoraid 9
octillery 12
delibird 13
mantine 13
skarmory 12
houndour 11
houndoom 12
kingdra 12
phanpy 9
donphan 13
porygon2 12
stantler 12
smeargle 12
tyrogue 12
hitmontop 12
smoochum 12
elekid 9
magby 10
miltank 15
blissey 9
raikou 13
entei 14
suicune 14
larvitar 9
pupitar 9
tyranitar 11
lugia 9
ho-oh 13
celebi 11
treecko 14
grovyle 14
sceptile 13
torchic 12
combusken 14
blaziken 14
mudkip 14
marshtomp 14
swampert 14
poochyena 14
mightyena 11
zigzagoon 14
linoone 11
wurmple 13
silcoon 9
beautifly 13
cascoon 8
dustox 14
lotad 13
lombre 12
ludicolo 15
seedot 11
nuzleaf 14
shiftry 13
taillow 15
swellow 15
wingull 14
pelipper 15
ralts 11
kirlia 13
gardevoir 12
surskit 12
masquerain 14
shroomish 11
breloom 15
slakoth 14
vigoroth 15
slaking 14
nincada 15
ninjask 13
shedinja 10
whismur 12
loudred 14
exploud 15
makuhita 12
hariyama 15
azurill 11
nosepass 11
skitty 11
delcatty 15
sableye 13
mawile 14
aron 9
lairon 12
aggron 12
meditite 13
medicham 13
electrike 10
manectric 13
plusle 10
minun 13
volbeat 15
illumise 15
roselia 15
gulpin 11
swalot 14
carvanha 13
sharpedo 14
wailmer 15
wailord 13
numel 15
camerupt 13
torkoal 12
spoink 13
grumpig 15
spinda 10
trapinch 10
vibrava 14
flygon 15
cacnea 14
cacturne 12
swablu 12
altaria 12
zangoose 15
seviper 14
lunatone 14
solrock 14
barboach 12
whiscash 15
corphish 13
crawdaunt 15
baltoy 7
claydol 12
lileep 12
cradily 12
anorith 14
armaldo 14
feebas 13
milotic 14
castform 9
kecleon 15
shuppet 12
banette 12
duskull 13
dusclops 11
tropius 15
chimecho 13
absol 11
wynaut 11
snorunt 15
glalie 13
spheal 12
sealeo 15
walrein 12
clamperl 14
huntail 14
gorebyss 12
relicanth 13
luvdisc 9
bagon 11
shelgon 12
salamence 13
beldum 10
metang 13
metagross 13
regirock 13
regice 10
registeel 13
latias 14
latios 14
kyogre 14
groudon 14
rayquaza 12
jirachi 12
deoxys 14
teamrocket 6
starterspairs 6
startersDark 6
pals
alphabet 26
alphabet2 26
glasbey 32
kelly 22
polychrome 36
stepped 24
tol 12
watlington 16
Polychrome
alphabet 26
dark 24
glasbey 32
green.armytage 26
kelly 22
light 24
palette36 36
rcartocolor
ag_Sunset 7
ag_GrnYl 7
Tropic 7
Temps 7
TealRose 7
Geyser 7
Fall 7
Earth 7
ArmyRose 7
Vivid 12
Safe 12
Prism 12
Pastel 12
Bold 12
Antique 12
TealGrn 7
Teal 7
SunsetDark 7
Sunset 7
RedOr 7
PurpOr 7
Purp 7
PinkYl 7
Peach 7
OrYel 7
Mint 7
Magenta 7
Emrld 7
DarkMint 7
BurgYl 7
Burg 7
BrwnYl 7
BluYl 7
BluGrn 7
RColorBrewer
BrBG 11
PiYG 11
PRGn 11
PuOr 11
RdBu 11
RdGy 11
RdYlBu 11
RdYlGn 11
Spectral 11
Accent 8
Dark2 8
Paired 12
Pastel1 9
Pastel2 8
Set1 9
Set2 8
Set3 12
Blues 9
BuGn 9
BuPu 9
GnBu 9
Greens 9
Greys 9
Oranges 9
OrRd 9
PuBu 9
PuBuGn 9
PuRd 9
Purples 9
RdPu 9
Reds 9
YlGn 9
YlGnBu 9
YlOrBr 9
YlOrRd 9
Redmonder
dPBIYlBu 11
dPBIYlPu 11
dPBIPuGn 11
dPBIPuOr 11
dPBIRdBu 11
dPBIRdGy 11
dPBIRdGn 11
qMSOStd 10
qMSO12 8
qMSO15 8
qMSOBuWarm 8
qMSOBu 8
qMSOBu2 8
qMSOBuGn 8
qMSOGn 8
qMSOGnYl 8
qMSOYl 8
qMSOYlOr 8
qMSOOr 8
qMSOOrRd 8
qMSORdOr 8
qMSORd 8
qMSORdPu 8
qMSOPu 8
qMSOPu2 8
qMSOMed 8
qMSOPap 8
qMSOMrq 8
qMSOSlp 8
qMSOAsp 8
qPBI 8
sPBIGn 9
sPBIGy1 9
sPBIRd 9
sPBIYl 9
sPBIGy2 9
sPBIBu 9
sPBIOr 9
sPBIPu 9
sPBIYlGn 9
sPBIRdPu 9
tidyquant
tq_light 12
tq_dark 12
tq_green 12
wesanderson
BottleRocket1 7
BottleRocket2 5
Rushmore1 5
Rushmore 5
Royal1 4
Royal2 5
Zissou1 5
Darjeeling1 5
Darjeeling2 5
Chevalier1 4
FantasticFox1 5
Moonrise1 4
Moonrise2 4
Moonrise3 5
Cavalcanti1 5
GrandBudapest1 4
GrandBudapest2 4
IsleofDogs1 6
IsleofDogs2 5
yarrr
basel 10
pony 9
xmen 8
decision 6
southpark 6
google 4
eternal 7
evildead 6
usualsuspects 7
ohbrother 7
appletv 6
brave 5
bugs 5
cars 5
nemo 5
rat 5
up 5
espresso 5
ipod 7
info 9
info2 14
The paletteer package is maintained by Emil Hvitfeldt. More information can be found on the paletteer site and on the CRAN info page.

Annotations mathématiques

Pour ajouter des annotation mathématiques à un graphique, comme une équation, on aura recours à la fonction expression. Les expressions qui peuvent être utilisées sont présentées en détail dans l’aide en ligne de plotmath, visible également sur http://www.rdocumentation.org/packages/grDevices/functions/plotmath.

Combiner texte et expression

On aura recours à la fonction paste à l’intérieur de l’appel à expression. Un exemple :

# données aléatoires
df <- data.frame(x = rnorm(100), y = rnorm(100))

library(ggplot2)
ggplot(df) +
  aes(x = x, y = y) +
  geom_point() +
  xlab(expression(hat(mu)[0])) +
  ylab(expression(alpha^beta)) +
  ggtitle(expression(paste("Plot of ", alpha^beta, " versus ", hat(mu)[0])))

Intégrer une valeur calculée dans une expression

Pour intégrer une valeur pré-calculée, et donc stockée dans un objet R, dans une expression, on aura recours à la fonction substitute.

x_mean <- 1.5
x_sd <- 1.2
df <- data.frame(x = rnorm(100, x_mean, x_sd))

ggplot(df) +
  aes(x = x) +
  geom_histogram(binwidth = .25) + 
  ggtitle(
    substitute(
      paste(X[i], " ~ N(", mu, "=", m, ", ", sigma^2, "=", s2, ")"),
      list(m = x_mean, s2 = x_sd^2)
    )
  )

Syntaxe de plotmath

demo(plotmath)

Calculer un âge

La version originale de cette astuce a été publiée par Joseph Larmarange sur http://joseph.larmarange.net/?Calculer-proprement-un-age-sous-R.

Le calcul d’un âge sous R n’est pas forcément aussi trivial qu’il n’y parait.

Rappel sur les âges

Il convient en premier lieu de rappeler les principaux âges utilisés les démographes :

L’âge – on précise parfois âge chronologique – est une des caractéristiques fondamentales de la structure des populations. On l’exprime généralement en années, ou en années et mois, voire en mois et jours, pour les enfants en bas âge ; parfois en années et fractions décimales d’année. Les démographes arrondissent d’ordinaire l’âge à l’unité inférieure, l’exprimant ainsi en années révolues, ou années accomplies, le cas échéant en mois révolus, ou mois accomplis. Cet âge est aussi l’âge au dernier anniversaire. On trouve aussi, dans les statistiques, l’âge atteint dans l’année, qui est égal à la différence de millésimes entre l’année considérée et l’année de naissance. […] On est parfois conduit à préciser que l’on considère un âge exact, pour éviter toute confusion avec un âge en années révolues, qui représente en fait une classe d’âges exacts.

Le package lubridate

Le package lubridate est spécialement développé pour faciliter la manipulation et le calcul autour des dates. La version de développement intègre depuis peu une fonction time_length adaptée au calcul des âges exacts.

La fonction time_length étant récente, elle n’est pas encore disponible dans la version stable du package. Pour installer la version de développement de lubridate, on aura recours au package devtools :

library(devtools)
install_github("tidyverse/lubridate")

Nous noterons naiss la date de naissance et evt la date à laquelle nous calculerons l’âge.

Calcul d’un âge exact

On appelle âge exact l’expression d’un âge avec sa partie décimale.

Une approche simple consiste à calculer une différence en jours puis à diviser par 365. Or, le souci c’est que toutes les années n’ont pas le même nombre de jours. Regardons par exemple ce qui se passe si l’on calcule l’âge au 31 décembre 1999 d’une personne née le 1er janvier 1900.

library(lubridate)
naiss <- ymd("1900-01-01")
evt <- ymd("1999-12-31")
time_length(interval(naiss, evt), "days")
[1] 36523
time_length(interval(naiss, evt), "days") / 365
[1] 100.063

Or, au 31 décembre 1999, cette personne n’a pas encore fêté son centième anniversaire. Le calcul précédent ne prend pas en compte les années bissextiles. Une approche plus correcte serait de considérer que les années durent en moyenne 365,25 jours.

time_length(interval(naiss, evt), "days") / 365.25
[1] 99.99452

Si cette approche semble fonctionner avec cet exemple, ce n’est plus le cas dans d’autres situations.

evt <- ymd("1903-01-01")
time_length(interval(naiss, evt), "days") / 365.25
[1] 2.997947

Or, à la date du premier janvier 1903, cette personne a bien fêté son troisième anniversaire.

Pour calculer proprement un âge en années (ou en mois), il est dès lors nécessaire de prendre en compte la date anniversaire et le fait que la durée de chaque année (ou mois) est variable. C’est justement ce que fait la fonction time_length appliquée à un objet de type Interval. On détermine le dernier et le prochain anniversaire et l’on rajoute, à l’âge atteint au dernier anniversaire, le ratio entre le nombre de jours entre l’événement et le dernier anniversaire par le nombre de jours entre le prochain et le dernier anniversaire.

naiss <- ymd("1900-01-01")
evt <- ymd("1999-12-31")
time_length(interval(naiss, evt), "years")
[1] 99.99726
evt <- ymd("1903-01-01")
time_length(interval(naiss, evt), "years")
[1] 3
evt <- ymd("1918-11-11")
time_length(interval(naiss, evt), "years")
[1] 18.86027

Attention, cela n’est valable que si l’on présente à la fonction time_length un objet de type Interval (pour lequel on connait dès lors la date de début et la date de fin). Si l’on passe une durée (objet de type Duration) à la fonction time_length, le calcul s’effectuera alors en prenant en compte la durée moyenne d’une année (plus précisément 365 jours).

naiss <- ymd("1900-01-01")
evt <- ymd("1999-12-31")
time_length(interval(naiss, evt), "years")
[1] 99.99726
time_length(evt - naiss, "years")
[1] 99.99452
time_length(as.duration(interval(naiss, evt)), "years")
[1] 99.99452

Cas particulier des personnes nées un 29 février

Pour les personnes nées un 29 février, il existe un certain flou concernant leur date d’anniversaire pour les années non bissextiles. Doit-on considérer qu’il s’agit du 28 février ou du 1er mars ?

Au sens strict, on peut considérer que leur anniversaire a lieu entre le 28 février soir à minuit et le 1er mars à 0 heure du matin, autrement dit que le 28 février ils n’ont pas encore fêté leur anniversaire. C’est la position adoptée par la fonction time_length.

naiss <- ymd("1992-02-29")
evt <- ymd("2014-02-28")
time_length(interval(naiss, evt), "years")
[1] 21.99726
evt <- ymd("2014-03-01")
time_length(interval(naiss, evt), "years")
[1] 22

Cette approche permets également d’être cohérent avec la manière dont les dates sont prises en compte informatiquement. On considère en effet que lorsque seule la date est précisée (sans mention de l’heure), l’heure correspondante est 0:00. Autrement dit, "2014-03-01" est équivalent à "2014-03-01 00:00:00". L’approche adoptée permet donc d’être cohérent lorsque l’anniversaire est calculé en tenant compte des heures.

naiss <- ymd("1992-02-29")
evt <- ymd_hms("2014-02-28 23:00:00")
time_length(interval(naiss, evt), "years")
[1] 21.99989
evt <- ymd_hms("2014-03-01 00:00:00")
time_length(interval(naiss, evt), "years")
[1] 22
evt <- ymd_hms("2014-03-01 01:00:00")
time_length(interval(naiss, evt), "years")
[1] 22.00011
naiss <- ymd_hms("1992-02-29 12:00:00")
evt <- ymd_hms("2014-03-01 01:00:00")
time_length(interval(naiss, evt), "years")
[1] 22.00011

Âge révolu ou âge au dernier anniversaire

Une fois que l’on sait calculer un âge exact, le calcul d’un âge révolu ou âge au dernier anniversaire est assez simple. Il suffit de ne garder que la partie entière de l’âge exact (approche conseillée).

naiss <- ymd("1980-01-09")
evt <- ymd("2015-01-01")
time_length(interval(naiss, evt), "years")
[1] 34.97808
trunc(time_length(interval(naiss, evt), "years"))
[1] 34

Une autre approche consiste à convertir l’intervalle en objet de type Period et à ne prendre en compte que les années.

as.period(interval(naiss, evt))
[1] "34y 11m 23d 0H 0M 0S"
as.period(interval(naiss, evt))@year
[1] 34

Âge par différence de millésimes

L’âge par différence de millésimes, encore appelé âge atteint dans l’année, s’obtient tout simplement en soustrayant l’année de naissance à l’année de l’événement.

naiss <- ymd("1980-01-09")
evt <- ymd("2015-01-01")
year(evt) - year(naiss)
[1] 35

Calcul d’un âge moyen

Le calcul d’un âge moyen s’effectue normalement à partir d’âges exacts. Il arrive fréquemment que l’on ne dispose dans les données d’enquêtes que de l’âge révolu. Auquel cas, il faut bien penser à rajouter 0,5 au résultat obtenu. En effet, un âge révolu peut être vu comme une classe d’âges exacts : les individus ayant 20 ans révolus ont entre 20 et 21 ans exacts, soit en moyenne 20,5 ans !

Notes

L’ensemble des fonctions présentées peuvent être appliquées à des vecteurs et, par conséquent, aux colonnes d’un tableau de données (data.frame).

En l’absence du package lubridate, il reste facile de calculer une durée en jours avec les fonctions de base de R :

naiss <- as.Date("1900-01-01")
evt <- as.Date("1999-12-31")
evt - naiss
Time difference of 36523 days
as.integer(evt - naiss)
[1] 36523

Index des concepts

A

ACM

ACP

AFC

âge

âge atteint dans l’année

âge au dernier anniversaire

âge exact

AIC

aide

aide en ligne

Akaike Information Criterion

aléatoire, échantillonnage

aléatoire, effet

analyse de séquences

analyse de survie

analyse des biographies

analyse des correspondances multiples

analyse en composante principale

analyse factorielle

analyse factorielle avec données mixtes

analyse factorielle des correspondances

ANOVA

appariement optimal

arbre de classification

argument

argument nommé

argument non nommé

assignation par indexation

assignation, opérateur

attribut

autocomplétion

B

barres cumulées, diagramme en

barres cumulées, graphique

barres, diagramme en

bâton, diagramme

bâtons, diagramme en

Bayesian Highest Density Intervals

binaire, régression logistique

biographie, analyse

bitmap

boîte à moustache

boîte à moustaches

booléenne, valeur

booléenne, variable

boxplot

C

CAH

camembert, graphique

caractères, chaîne

catégorielle, variable

censure à droite

cercle de corrélation

chaîne de caractères

character

chemin relatif

Chi², distance

Chi², résidus

Chi², test

chunk

classe de valeurs

classe, homogénéité

classes latentes, modèle mixte

classification ascendante hiérarchique

classification, arbre

Cleveland, diagramme

cluster

coefficient de contingence de Cramer

coefficient de corrélation

coefficient, modèle

coefficients du modèle

colinéarité

coloration syntaxique

commentaire

comparaison de courbes de survie (test du logrank)

comparaison de médianes, test

comparaison de moyennes

comparaison de proportions, test

comparaison, opérateur

Comprehensive R Archive Network

condition, indexation

confusion, matrice

console

corrélation

corrélation, cercle

corrélation, coefficient

corrélation, matrice de

correspondances, analyse factorielle

couleur

couleur, palette

courbe de densité

Cox, modèle

Cramer, coefficient de contingence

CRAN

croisé, tableau

CSV, fichier

D

data frame

data.frame

date, variable

dendrogramme

densité, courbe de

densité, estimation locale

descriptive, statistique

design

diagramme de Cleveland

diagramme de Lexis

diagramme de Sankey

diagramme en barres

diagramme en barres cumulées

diagramme en bâtons

diagramme en secteur

distance

distance de Gower

distance du Chi²

distance du Phi²

distance, matrice

distribution

donnée labelissée

données pondérées

données, exporter

données, tableau

droite de régression

droite, censure

E

écart-type

écart interquartile

échantillonnage aléatoire simple

échantillonnage équiprobable

échantillonnage par grappes

échantillonnage stratifié

échantillonnage, plan

éditeur de script

effet aléatoire

effet d’interaction

empirical cumulative distribution function

entier

entier, nombre

entropie transversale

environnement de développement

environnement de travail

équiprobable, échantillonnage

erreurs

estimation locale de densité

estimation par noyau

étendue

étiquette de valeur

étiquette de variable

étiquettes de valeurs

event history analysis

exact, âge

explicative, variable

export de graphiques

exporter des données

expression régulière

extension

F

facteur

facteurs d’inflation de la variance

factor

factoriel, plan

factorielle, analyse

fichier CSV

fichier de commandes

fichier texte

fichiers Shapefile

Fisher, test exact

FIV

fonction

fonction de répartition empirique

formule

fréquence, tableau

fusion

fusion de tables

G

GEE, modèle

gestionnaire de versions

Gower, distance

Gower, indice de similarité

grammaire des tableaux

graphique de pirates

graphique en mosaïque

graphique en violon

graphique, export

grappe, échantillonnage

H

hazard ratio

hazard ratio (HR)

HDI

histogramme

historique des commandes

homogénéité des classes

I

image bitmap

image matricielle

image vectorielle

indépendance

indertie, perte relative

index plots

indexation

indexation bidimensionnelle

indexation directe

indexation par condition

indexation par nom

indexation par position

indexation, assignation

indice de similarité

indice de similarité de Gower

inertie

inertie, saut

installation

integer

interaction

intercept

interface

interquartilen écart

intervalle de confiance

intervalle de confiance d’un odds ratio

intervalle de confiance d’une moyenne

intervalle de confiance d’une proportion

invite de commande

K

Kaplan-Meier

L

labelled data

labellisé, vecteur

labellisée, donnée

labellisée, variable

latente, modèle mixte à classes latentes

LCS

level, factor

Lexis, diagramme

libre, logiciel

life course analysis

linéaire, régression

liste

logical

logiciel libre

logique, opérateur

logique, valeur

logistique, régression

logrank, test (comparaison de courbes de survie)

loi normale

Longuest Common Subsequence

M

Mann-Whitney, test

manquante, valeur

Markdown

matching, optimal

matrice de confusion

matrice de corrélation

matrice de distances

maximum

médiane

médiane, test de comparaison

métadonnée

méthode de Ward

minimum

mise à jour, R

mixte, modèle

mixte, modèle mixte à classes latentes

mixtes, analyse factorielle avec données

modalité

modalité de référence

modalité, facteur

modèle à effets aléatoires

modèle de Cox

modèle GEE

modèle linéaire généralisé

modèle mixte

modèle, coefficients

modèle, résidus

mosaïque, graphique

moustaches, boîte

moyenne

moyenne, âge

moyenne, comparaison

moyenne, intervalle de confiance

multi-états, modèle de survie

multicolinéarité

multicolinéarité parfaite

multidimensional scaling

multinomiale, régression logistique

N

NA

nom, indexation

nombre entier

nombre réel

normale, loi

normalité, test de Shapiro-Wilk

notation formule

notation scientifique

noyau, estimation

nuage de points

numeric

numérique, variable

O

observation

observations répétées, modèle

odds ratio

odds ratio, intervalle de confiance

opérateur de comparaison

opérateur logique

optimal matching

optimal, appariement

ordinaire, régression logistique

ordinale, régression logistique

ordonner le tri à plat

P

package

palette de couleurs

PAM

partition

Partitioning Around Medoids

pas à pas, sélection descendante

patron

perte relative d’inertie

Phi², distance

pirate, graphique

pirateplot

plan d’échantillonnage

plan factoriel

poids de réplication

points, nuage de

pondération

pooled variance

position, indexation

projets

prompt

proportion, intervalle de confiance

proportion, test de comparaison

proxy

Q

qualitative, variable

quantile

quantitative, variable

quartile

R

R Markdown

rapport des cotes

raster

recodage de variables

recyclage

recycling rule

réel, nombre

référence, modalité

régression linéaire

régression logistique

régression logistique binaire

régression logistique multinomiale

régression logistique ordinaire

régression logistique ordinale

régression, droite

régulière, expression

relatif, risque

relation fonctionnelle

répartition empirique, fonction

répertoire de travail

réplication, poids

résidus de Schoenfeld

résidus du modèle

résidus, test du Chi²

résolution

ressemblance

révolu, âge

risque relatif

S

Sankey, diagramme

SAS, fichier

saut d’inertie

Schoenfeld, résidus

scientifique, notation

script

scripts

secteur, diagramme

section

sélection descendante pas à pas

séparateur de champs

séparateur décimal

séquence, analyse

séquence, tapis

Shapiro-Wilk, test de normalité

similarité, indice

sous-échantillon

SPSS, fichier

statistique bivariée

statistique descriptive

statistique univariée

strate

stratifié, échantillonnage

structure d’un objet

Student, test-t

Student, test t

survie, analyse

survie, modèle multi-états

T

tableau croisé

tableau croisé, coefficient de contingence de Cramer

tableau croisé, graphique en mosaïque

tableau croisé, test exact de Fisher

tableau de donnée

tableau de données, fusion

tableau de données, tri

tableau de fréquences

tagged missing value

tagged NA

tapis

task view

test d’égalité des variances

test de comparaison de deux proportions

test de normalité de Shapiro-Wilk

test de Wilcoxon/Mann-Whitney

test du Chi²

test du Chi², résidus

test exact de Fisher

test t de Student

texte

texte tabulé, fichier

texte, fichier

tibble

tidy data

tidyverse

total

trajectoire biographique

transversale, entropie

tri à plat

tri à plat, ordonner

U

univariée, statistique

V

valeur booléenne

valeur logique

valeur manquante

valeur manquante déclarée

valeur, étiquette

variable

variable catégorielle

variable d’intérêt

variable explicative

variable labellisée

variable numérique

variable qualitative

variable quantitative

variable, étiquette

variable, recodage

variance

variance inflation factor

variance, analyse de

variance, pooled

variance, test d’égalité

vecteur

vecteur labellisé

vector

viewer

VIF

violin plot

violon, graphique en

visionneusee

W

Ward, méthode

Wilcoxon, test

Index des fonctions

%

%in% (base)

.

.N (data.table)

A

A2Rplot (JLutils)

aaply (plyr)

abline (graphics)

add.NA (base)

add_global_p (gtsummary)

add_overall (gtsummary)

add_p (gtsummary)

addNA (base)

addNAstr (questionr)

adply (plyr)

aes (ggplot2)

aggregate (stats)

agnes (cluster)

AIC (stats)

AIC.svyglm (survey)

airlines (nycflights13)

airports (nycflights13)

allEffects (effects)

alply (plyr)

anova (geepack)

anova (stats)

Anova (car)

anti_join (dplyr)

aov (stats)

append (base)

apply (base)

arrange (dplyr)

array (base)

as.character (base)

as.clustrange (WeightedCluster)

as.data.frame (base)

as.data.frame (tibble)

as.data.table (data.table)

as.hclust (cluster)

as.integer (base)

as.matrix (base)

as.numeric (base)

as.seqtree (WeightedCluster)

as_factor (haven)

as_tibble (tibble)

B

barchart (lattice)

barplot (graphics)

base (base)

beep (beepr)

best.cutree (JLutils)

bind_cols (dplyr)

bind_rows (dplyr)

biplot (ade4)

boxplot (ade4)

boxplot (graphics)

break (base)

brewer.pal (RColorBrewer)

bwplot (lattice)

by (base)

C

c (base)

CA (FactoMineR)

case_when (dplyr)

cbind (base)

chisq.residuals (questionr)

chisq.test (stats)

class (base)

clm (ordinal)

clmm (ordinal)

cm.colors (grDevices)

cmdscale (stats)

coef (stats)

coef (survey)

collect (dplyr)

colorblind_pal (ggthemes)

colors (grDevices)

column_to_rownames (tibble)

comma (scales)

complete (tidyr)

complete.cases (stats)

confint (stats)

confint (survey)

confint (svrepmisc)

contains (dplyr)

contour (graphics)

coord_capped_cart (lemon)

coord_capped_flip (lemon)

coord_flip (ggplot2)

copy_labels_from (labelled)

cor (stats)

corresp (MASS)

count (dplyr)

cox.zph (survival)

cprop (questionr)

cramer.v (questionr)

create_report (DataExplorer)

cut (base)

cutree (stats)

D

daisy (cluster)

daply (plyr)

data (utils)

data.frame (base)

datatable (DT)

dbConnect (DBI)

dbDisconnect (DBI)

dbGetQuery (DBI)

dbListFields (DBI)

dbListTables (DBI)

dbReadTable (DBI)

dcast (data.table)

ddply (plyr)

density (stats)

densityplot (lattice)

describe (questionr)

dev.off (grDevices)

dev.print (grDevices)

dim (base)

dimdesc (FactoMineR)

display.brewer.all (RColorBrewer)

disscenter (TraMineR)

dist (stats)

dist.dudi (ade4)

distinct (dplyr)

diverging_bar_chart (ggcharts)

diverging_lollipop_chart (ggcharts)

dlply (plyr)

do.call (base)

dotchart (graphics)

dotplot (lattice)

dput (base)

drop1 (stats)

dudi.acm (ade4)

dudi.coa (ade4)

dudi.mix (ade4)

dudi.pca (ade4)

Duration (lubridate)

E

effect (effects)

else (base)

ends_width (dplyr)

example (utils)

exp (base)

expression (base)

extract (tidyr)

F

facet_grid (ggplot2)

facet_rep_grid (lemon)

facet_rep_wrap (lemon)

facet_wrap (ggplot2)

factor (base)

FAMD (FactoMineR)

fct_collapse (forcats)

fct_explicit_na (forcats)

fct_inorder (forcats)

fct_lump (forcats)

fct_other (forcats)

fct_recode (forcats)

fct_reorder (forcats)

few_pal (ggthemes)

filled.contour (graphics)

filter (dplyr)

finalfit (finalfit)

first (data.table)

fisher.test (stats)

fixed (stringr)

flights (nycflights13)

for (base)

forest_model (forestmodel)

format (base)

formula (stats)

freq (questionr)

ft_pal (hrbrthemes)

full_join (dplyr)

G

gather (tidyr)

geom_alluvium (ggalluvial)

geom_area (ggplot2)

geom_bar (ggplot2)

geom_bin2d (ggplot2)

geom_boxplot (ggplot2)

geom_braket (ggpubr)

geom_count (ggplot2)

geom_density (ggplot2)

geom_density_2d (ggplot2)

geom_density_ridges_gradient (ggridges)

geom_dumbbell (ggalt)

geom_errorbarh (ggplot2)

geom_hex (ggplot2)

geom_histogram (ggplot2)

geom_label_repel (ggrepel)

geom_line (ggplot2)

geom_lollipop (ggalt)

geom_mosaic (ggmosaic)

geom_pirate (ggpirate)

geom_point (ggplot2)

geom_raster (ggplot2)

geom_rug (ggplot2)

geom_smooth (ggplot2)

geom_stratum (ggalluvial)

geom_text (ggplot2)

geom_text_repel (ggrepel)

geom_violin (ggplot2)

geom_vline (ggplot2)

geom_waffle (waffle)

get_legend (cowplot)

getValues (raster)

getwd (base)

ggbivariate (GGally)

ggcoef (GGally)

ggcorr (GGally)

ggcoxzph (survminer)

ggdendrogram (ggdendro)

ggduo (GGally)

ggeffect (ggeffect)

ggeffect (ggeffects)

ggforest (survminer)

gghiglight (gghiglight)

ggpairs (GGally)

ggplot (ggplot2)

ggplotly (plotly)

ggsave (ggplot2)

ggsurv (GGally)

ggsurvey (JLutils)

ggsurvplot (survminer)

ggtable (GGally)

ggtitle (ggplot2)

glimpse (dplyr)

glimpse (tibble)

glm (stats)

glmulti (ggmulti)

grid_arrange_shared_legend (lemeon)

group_by (dplyr)

grViz (DiagrammeR)

H

haven_labelled (haven)

haven_labelled (labelled)

hazard.msm (msm)

hclust (fastcluster)

hclust (stats)

HCPC (FactoMineR)

hdv2003 (questionr)

head (utils)

heat.colors (grDevices)

help (utils)

help.search (utils)

help.start (utils)

hist (graphics)

histogram (lattice)

I

icut (questionr)

if (base)

if_else (dplyr)

ifelse (base)

image (graphics)

inertia.dudi (ade4)

inner_join (dplyr)

install.packages (utils)

install_github (devtools)

interaction (base)

Interval (lubridate)

invisible (base)

iorder (questionr)

ipsum_pal (hrbrthemes)

irec (questionr)

is.na (base)

is.numeric (base)

J

jpeg (grDevices)

K

kable (knitr)

kde2d (MASS)

L

labelled (labelled)

labs (ggplot2)

lag (dplyr)

lapply (base)

last (data.table)

lcmm (lcmm)

lead (dplyr)

left_join (dplyr)

length (base)

letters (base)

LETTERS (base)

levels (base)

library (base)

list (base)

llpply (plyr)

lm (stats)

load (base)

log (base)

look_for (labelled)

lookfor (questionr)

lprop (questionr)

ltabs (questionr)

M

makeCodebook (dataMaid)

maply (plyr)

mapply (base)

matches (dplyr)

max (base)

mca (MASS)

MCA (FactoMineR)

mcmcsamp (lme4)

mdply (plyr)

mean (base)

median (stats)

melt (data.table)

merge (base)

merge (data.table)

mermaid (DiagrammeR)

min (base)

mlply (plyr)

month.abb (base)

month.name (base)

mosaic (vcd)

mosaicplot (graphics)

msm (msm)

multinom (nnet)

multiplot (JLutils)

mutate (dplyr)

N

NA (base)

na_range (labelled)

na_values (labelled)

names (base)

ncol (base)

nesting (tidyr)

next (base)

nolabel_to_na (labelled)

nrow (base)

nth (dplyr)

NULL (base)

number (scales)

O

odds.ratio (questionr)

oneway.test (stats)

or_plot (final_fit)

or_plot (finalfilt)

order (base)

order (data.table)

ordgee (geepack)

ordinal (scales)

ordLORgee (multgee)

P

paged_table (rmarkdown)

pairs (graphics)

panel.xyplot (lattice)

par (graphics)

paste (base)

paste0 (base)

PCA (FactoMineR)

pdf (grDevices)

percent (scales)

Period (lubridate)

pi (base)

pie (graphics)

pirateplot (yarr)

pivot_longer (tidyr)

pivot_wider (tidyr)

plot (effects)

plot (FactoMineR)

plot (graphics)

plot (stats)

plot.prevalence.msm (msm)

plot_grid (cowplot)

plotellipses (FactoMineR)

plotmath (grDevices)

png (grDevices)

poly (stats)

position_dodge (ggplot2)

position_fill (ggplot2)

position_stack (ggplot2)

postprob (lcmm)

postscript (grDevices)

predict (stats)

predict (survey)

prevalence.msm (msm)

princomp (stats)

print (questionr)

progress_bar (progress)

prop (questionr)

prop.ci (JLutils)

prop.ci.lower (JLutils)

prop.ci.upper (JLutils)

prop.table (base)

prop.test (stats)

ptol_pal (ggthemes)

pvalue (scales)

pyramid_chart (ggcharts)

Q

qnorm (stats)

qplot (ggplot2)

quant.cut (questionr)

quantile (stats)

R

rainbow (grDevices)

range (base)

range (stats)

rank (base)

raster (raster)

rbind (base)

rbind.fill (plyr)

read.csv (utils)

read.csv2 (utils)

read.dbf (foreign)

read.delim (utils)

read.delim2 (utils)

read.dta (foreign)

read.spss (foreign)

read.table (utils)

read.xlsx (openxlsx)

read.xlsx (xlsx)

read.xlsx2 (xlsx)

read.xport (foreign)

read_csv (readr)

read_csv2 (readr)

read_delim (readr)

read_dta (haven)

read_excel (readxl)

read_feather (feather)

read_sas (haven)

read_spss (haven)

read_stata (haven)

read_tsv (readr)

readAsciiGrid (maptools)

readShapeLines (maptools)

readShapePoints (maptools)

readShapePoly (maptools)

readShapeSpatial (maptools)

recode (dplyr)

recode.haven_labelled (labelled)

recode_factor (dplyr)

rect.hclust (stats)

regex (stringr)

registerDoMC (doMC)

relevel (stats)

relocate (dplyr)

relrisk (mosaic)

remove.packages (utils)

remove_labels (labelled)

rename (dplyr)

rename.variable (questionr)

rep (base)

repeat (base)

require (base)

rgb (grDevices)

right_join (dplyr)

row.names (base)

rownames_to_column (tibble)

rownames_to_columns (tibble)

rprop (questionr)

rug (graphics)

runif (stats)

S

s.arrow (ade4)

s.chull (ade4)

s.class (ade4)

s.corcicle (ade4)

s.freq (JLutils)

s.hist (ade4)

s.label (ade4)

s.value (ade4)

sample_frac (dplyr)

sample_n (dplyr)

sankeyNetwork (networkD3)

sapply (base)

save (base)

save.image (base)

scale_color_paletteer_c (paletteer)

scale_color_paletteer_d (paletteer)

scale_colour_brewer (ggplot2)

scale_colour_viridis_c (ggplot2)

scale_colour_viridis_d (ggplot2)

scale_coulour_gradientn (ggplot2)

scale_fill_brewer (ggplot2)

scale_fill_gradientn (ggplot2)

scale_fill_viridis_c (ggplot2)

scale_fill_viridis_d (ggplot2)

scale_x_continuous (ggplot2)

scale_x_log10 (ggplot2)

scale_y_continuous (ggplot2)

scatter (ade4)

score (ade4)

screeplot (ade4)

sd (stats)

select (dplyr)

select_helpers (tidyselect)

semi_join (dplyr)

separate (tidyr)

seq (base)

seq_heatmap (JLutils)

seqcost (TraMineR)

seqdef (TraMineR)

seqdist (TraMineR)

seqdplot (TraMineR)

seqfplot (TraMineR)

seqHtplot (TraMineR)

seqIplot (TraMineR)

seqlength (TraMineR)

seqmsplot (TraMineR)

seqmtplot (TraMineR)

seqplot (TraMineR)

seqrep (TraMineR)

seqrplot (TraMineR)

seqsubm (TraMineR)

seqtreedisplay (TraMineR)

setDF (data.table)

setDT (data.table)

setorder (data.table)

setwd (base)

shapiro.test (stats)

skim (skimr)

slice (dplyr)

smean.sd (Hmisc)

smoothScatter (graphics)

sort (base)

sort_val_labels (labelled)

source (base)

SpatialGridDataFrame (sp)

spread (tidyr)

starts_with (dplyr)

stat_count (ggplot2)

stat_density_2d (ggplot2)

stat_ecdf (ggplot2)

stat_prop (GGally)

statetable.msm (msm)

step (stats)

stepAIC (MASS)

str (utils)

str_c (stringr)

str_count (stringr)

str_detect (stringr)

str_extract (stringr)

str_extract_all (stringr)

str_glue_data (stringr)

str_replace (stringr)

str_replace_all (stringr)

str_split (stringr)

str_sub (stringr)

str_subset (stringr)

str_to_lower (stringr)

str_to_title (stringr)

str_to_upper (stringr)

subset (base)

subset (data.table)

subset (survey)

substitute (base)

sum (base)

summarise (dplyr)

summarize (Hmisc)

summary (ade4)

summary (base)

summary (stats)

summary_factorlist (finalfit)

Surv (survival)

survdiff (survival)

survfit (survival)

svg (grDevices)

svyboxplot (survey)

svyby (survey)

svychisq (survey)

svyciprop (survey)

svyclm (svrepmisc)

svycoxph (survey)

svydesign (survey)

svyglm (survey)

svyhist (survey)

svykm (survey)

svymean (survey)

svymultinom (svrepmisc)

svyolr (survey)

svyplot (survey)

svyquantile (survey)

svyranktest (survey)

svyratio (survey)

svytable (survey)

svytotal (survey)

svyttest (survey)

svyvar (survey)

switch (base)

T

t.test (stats)

table (base)

tagged_na (haven)

tail (utils)

tally (dplyr)

tapply (base)

tbl (dplyr)

tbl_cross (gtsummary)

tbl_df (dplyr)

tbl_merge (gtsummary)

tbl_regression (gtsummary)

tbl_summary (gtsummary)

tbl_svysummary (gtsummary)

terrain.colors (grDevices)

theme (ggplot2)

theme_tufte (ggthemes)

tibble (tibble)

tidi_plus_plus (broom.helpers)

tidy (broom)

tidy (JLutils)

tidy (svrepmisc)

tidy.hazard.msm (JLutils)

tidy_plus_plus (broom.helpers)

tiff (grDevices)

time_length (lubridate)

to_character (labelled)

to_factor (labelled)

ToothGrowth (datasets)

topo.colors (grDevices)

trunc (base)

txtProgressBar (utils)

typeof (base)

U

unclass (base)

ungroup (dplyr)

unit (scales)

unite (tidyr)

unlabelled (labelled)

unlist (base)

unname (base)

update.packages (utils)

user_na_to_na (labelled)

V

val_label (labelled)

val_labels (labelled)

val_labels_to_na (labelled)

vapply (base)

var (base)

var (stats)

var.test (stats)

var_label (labelled)

Vectorize (base)

vglm (VGAM)

View (utils)

vif (car)

W

wcClusterQuality (WeightedCluster)

wcKMedoids (WeightedCluster)

wcSilhouetteObs (WeightedCluster)

weights (survey)

while (base)

win.metafile (grDevices)

write.csv (utils)

write.dbf (foreign)

write.dta (foreign)

write.foreign (foreign)

write.table (utils)

write.xlsx (openxlsx)

write.xlsx (xlsx)

write_csv (reader)

write_csv (readr)

write_delim (reader)

write_dta (haven)

write_feather (feather)

write_sas (haven)

write_sav (haven)

write_tsv (reader)

writeAsciiGrid (maptools)

writeLinesShape (maptools)

writePointsShape (maptools)

writePolyShape (maptools)

X

xlab (ggplot2)

xtabs (stats)

xyplot (lattice)

Y

ylab (ggplot2)

Index des extensions

A

ade4

B

base

beepr

breakDown

broom

broom.helpers

C

car

circlize

cluster

codebook

cowplot

D

data.table

DataExplorer

dataMaid

datasets

DBI

dbplyr

dendextend

devtools

DiagrammeR

distill

doBy

doMC

doSMP

dplyr

DT

dtplyr

E

ecdf

effects

esquisse

explor

extrafont

F

factoextra

FactoInvestigate

FactoMineR

Factoshiny

fastcluster

feather

final_fit

finalfilt

finalfit

flextable

forcats

foreign

forestmodel

formattable

G

gapminder

gee

geepack

ggalluvial

GGally

ggalt

gganimate

ggcharts

ggdendro

ggeffect

ggeffects

ggendro

ggfortify

gghighlight

gghiglight

ggmap

ggmosaic

ggmulti

ggpirate

ggplot2

ggplotAssist

ggpubr

ggrepel

ggridges

ggsci

ggThemeAssist

ggthemes

ggvis

gifski

glmulti

glue

googlesheets

gpplot2

graphics

grDevices

grid

gridExtra

gt

gtsummary

H

haven

highcharter

Hmisc

hrbrthemes

J

JLutils

K

kableExtra

khroma

knitr

L

laballed

labelled

lattice

latticeExtra

lcmm

lemeon

lemon

LexisPlotR

lme4

lubridate

M

magrittr

maptools

mapview

MASS

mctest

memisc

mlogit

mosaic

msm

msSurv

multgee

N

networkD3

nlme

nnet

nycflights13

O

openxlsx

ordinal

P

packrat

paletteer

pander

patchwork

phia

plotly

plyr

printr

productplots

progress

purrr

Q

question

questionr

R

raster

RColorBrewer

reader

readr

readxl

reshape2

revealjs

riverplot

rmarkdown

rmdformats

rmdshower

RSQLite

rvest

S

sankeyNetwork

scales

sf

sjPlot

skimr

sp

srvyr

stats

stringi

stringr

survey

survival

survminer

svrepmisc

T

tables

tibble

tidyr

tidyselect

tidyverse

tmap

TraMineR

TraMineRextras

U

utils

V

vcd

VGAM

viridis

W

waffle

WeightedCluster

X

xlsx

xtable

Y

yarr

yarrr